ExcelDataReader - Index was outside the bounds of the array - c#

fileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
I've used the above code to read an Excel document, You use no1 or no2 depending on whether it is xls or xlsx, I've tried it with xlsx (using number 2 above and it works fine - however I'm using another plug in to export the document again- and this only works with xls, so I wanted to keep the excel data reader to 'xls' when I use this code (number 1 instead of number 2-(numbered above) I get an error when trying to read in the file:
index was outside the bounds of the array
Any idea as to why?

Related

Unable to use Workbook and Worksheet objects for converting excel file to DataTable

I've been refering to this for adding excel to datatable, but the Workbook and Worksheet objects are not being identified as a objects
(I'm a beginner in c#)
Here is the code
using System.Data;
using System;
class Program
{
static void Main(string[] args)
{
// Create a file stream containing the Excel file to be opened
FileStream fstream = new FileStream("employees_tb.xlsx", FileMode.Open);
// Instantiate a Workbook object
//Opening the Excel file through the file stream
Workbook workbook = new Workbook(fstream);
// Access the first worksheet in the Excel file
Worksheet worksheet = workbook.Worksheets[0];
// Export the contents of 2 rows and 2 columns starting from 1st cell to DataTable
DataTable dataTable = worksheet.Cells.ExportDataTable(0, 0, 2, 2, true);
// Bind the DataTable with DataGrid
dataGridView1.DataSource = dataTable;
// Close the file stream to free all resources
fstream.Close();
}
}
You have not added de Aspose.Cells package in your solution. Try adding it via Project > Manage Nuget Packages >"Aspose.cells"

Using how to import data set into excel and return as memorystream? receiving an error inside workbook.Save(stream)

public static MemoryStream GenerateExcelReport(DataSet objDS)
{
// Instantiating a Workbook object
Workbook workbook = new Workbook();
// Obtaining the reference of the worksheet
Worksheet worksheet = workbook.Worksheets[0];
// Instantiating a "Products" DataTable object
DataTable dataTable = objDS.Tables[0];
// Importing the contents of DataTable to the worksheet starting from "A1" cell,
// Where true specifies that the column names of the DataTable would be added to
// The worksheet as a header row
worksheet.Cells.ImportDataTable(dataTable, true, "A1");
MemoryStream stream = new MemoryStream();
// Saving the Excel file
workbook.Save(stream);
return stream;
}
Workbook has two Save methods that accept Stream.
public void Save(Stream stream, SaveFormat saveFormat) where SaveFormat represents the format in which the workbook is saved.
public void Save(Stream stream, SaveOptions saveOptions) where SaveOptions represents all save options.
You need to specify the second argument either SaveFormat or SaveOptions.
Try to call Save with one of possible SaveFormat value like Xlsx.
Example:
// Saving the Excel file
workbook.Save(stream, SaveFormat.Xlsx);

Error when trying to read an .xls file using EPPlus

The following code is working fine for .xlsx, but it's not working for .xls. I got this error message
Can not open the package. Package is an OLE compound document. If this is an encrypted package, please supply the password
Code
string filepath = txtBrowse.Text;
FileStream stream = System.IO.File.Open(filepath, FileMode.Open, FileAccess.ReadWrite);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
FileInfo newFile = new FileInfo(filepath);
using (ExcelPackage package = new ExcelPackage(newFile))
{
string sheetName = System.DateTime.Now.ToShortDateString();
foreach (OfficeOpenXml.ExcelWorksheet sheet in package.Workbook.Worksheets)
{
// Check the name of the current sheet
if (sheet.Name == sheetName)
{
package.Workbook.Worksheets.Delete(sheetName);
break; // Exit the loop now
}
}
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(System.DateTime.Now.ToShortDateString());
}
How do I do this correctly?
EPPlus does not work with the XLS format. Only XLSX. You'll need to find a new library.
I succesfully used Tony's answer https://stackoverflow.com/a/18904633/306515 and simply convert it using Microsoft.Office.Interop.Excel and can still then use epplus

Find and replace value in Excel using C#

How can I find some value from cell and replace by new value in Excel?
I tryed this but it doesn't works:
Microsoft.Office.Interop.Excel.Application xlapp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook wb =default(Microsoft.Office.Interop.Excel.Workbook);
wb = xlapp.Workbooks.Open(FileName.ToString());
wb.Worksheets[0].Cells.Replace("find","replace");
I would recommend you use NPOI which can be accessed either via codeplex or directly through Nuget in Visual Studio. It gives you the ability to easily upload, edit and create spreadsheets in .NET
Example of uploading a spreadsheet:
HSSFWorkbook hssfworkbook;
void InitializeWorkbook(string path)
{
//read the template via FileStream, it is suggested to use FileAccess.Read to prevent file lock.
//book1.xls is an Excel-2007-generated file, so some new unknown BIFF records are added.
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
hssfworkbook = new HSSFWorkbook(file);
}
}
You can then use the IRow and ICell collections of the spreadsheet to locate and edit the data you need before doing an export.
More examples can be found here
If interested, you can use GemBox.Spreadsheet for this, like so:
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
// Load your XLS, XLSX, ODS or CSV file.
ExcelFile wb = ExcelFile.Load(FileName.ToString());
ExcelWorksheet ws = wb.Worksheets[0];
// Replace all "find" occurances with "replace" text.
int row, column;
while(ws.Cells.FindText("find", out row, out column))
ws.Cells[row, column].ReplaceText("find", "replace");
// Save your XLS, XLSX, ODS or CSV file.
wb.Save(FileName.ToString());
Also you can find another searching in Excel example here.
All you have to do is replace
wb.Worksheets[0].Cells.Replace("find","replace");
with
wb.Worksheets[1].Cells.Replace("find","replace");

Convert xls or xlsx file with multiple sheets into one csv file using interop

I am trying to convert a xls or xlsx file with multiple sheets into one CSV file using c# and the interop library. I am only getting the one sheet in the CSV file. I know I can specify the sheet to save as or change the active sheet to save that one but I am looking for a solution to append all the sheets to the same CSV file that will work with both xls and xlsx files. I am automating this and don't care what is in the excel document just want to pull the string values out and append it to the csv file. Here is the code I am using:
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
app.DisplayAlerts = false;
Workbook wkb = app.Workbooks.Open(fullFilePath);
wkb.SaveAs(newFileName, XlFileFormat.xlCSVWindows);
Is this even possible?
I'm just getting started tackling a similar situation, but I believe this may address your needs:
http://www.codeproject.com/Articles/246772/Convert-xlsx-xls-to-csv
This uses the ExcelDataReader api that you can get from NuGet
http://exceldatareader.codeplex.com/
Like Tim was saying, you're going to have to make sure and possibly validate that the columns and structure are the same between sheets. You may also have to eat the header rows on all the sheets after the first one. I'll post an update and some code samples once I've finished.
Update [7/15/2013]. Here's my finished code. Not very fancy, but it gets the job done. All of the sheets are tables in the DataSet, so you just loop through the tables adding onto your destination. I'm outputting to a MongoDB, but I'm guessing you can swap that out for a StreamWriter for your CSV file rather easily.
private static void ImportValueSetAttributeFile(string filePath)
{
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
// Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
// Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
var connectionString = ConfigurationManager.ConnectionStrings[0].ConnectionString;
var database = ConfigurationManager.AppSettings["database"];
var mongoAccess = new MongoDataAccess(connectionString, database);
var cdm = new BaseDataManager();
int ind = 0;
for (int i = 0; i < result.Tables.Count; i++)
{
int row_no = 1;
while (row_no < result.Tables[ind].Rows.Count) // ind is the index of table
// (sheet name) which you want to convert to csv
{
var currRow = result.Tables[ind].Rows[row_no];
var valueSetAttribute = new ValueSetAttribute()
{
CmsId = currRow[0].ToString(),
NqfNumber = currRow[1].ToString(),
ValueSetName = currRow[2].ToString(),
ValueSetOid = currRow[3].ToString(),
Definition = currRow[4].ToString(),
QdmCategory = currRow[5].ToString(),
Expansion = currRow[6].ToString(),
Code = currRow[7].ToString(),
Description = currRow[8].ToString(),
CodeSystem = currRow[9].ToString(),
CodeSystemOid = currRow[10].ToString(),
CodeSystemVersion = currRow[11].ToString()
};
cdm.AddRecords<ValueSetAttribute>(valueSetAttribute, "ValueSetAttributes");
row_no++;
}
ind++;
}
}

Categories