Exporting Data to Excel very Slow - c#

I am trying to export data from my C# code to MS Excel 2007, but it is taking 30 seconds to insert data in an excel file.The code is like this->
Excel.Application excelapp = new Excel.Application();
Excel.Workbook excelworkbook = excelapp.Workbooks.Open(fileTest);
Excel.Sheets excelsheets = excelworkbook.Worksheets;
Excel.Worksheet mysheets = (Excel.Worksheet)excelsheets.get_Item("Sheet1");
Excel.Range mycells = mysheets.Cells;
mycells.Item[destroyer, "A"].Value = s[2];
mycells.Item[destroyer, "B"].Value = s[1];
mycells.Item[destroyer, "C"].Value = s[3];
mycells.Item[destroyer, "D"].Value = dbl_standard.Text;
mycells.Item[destroyer, "E"].Value = s[4];
mycells.Item[destroyer, "F"].Value = s[7];
mycells.Item[destroyer, "G"].Value = s[5];
mycells.Item[destroyer, "H"].Value = s[6];
excelworkbook.Save();
excelworkbook.Close();
excelapp.Quit();
Marshal.ReleaseComObject(mycells);
Marshal.ReleaseComObject(mysheets);
Marshal.ReleaseComObject(excelsheets);
Marshal.ReleaseComObject(excelworkbook);
Marshal.ReleaseComObject(excelapp);
I am inserting hardly 25 columns.Which thing am I doing wrong?How to make it fast?
Thanks in Advance

You have two issues going on here. The first issue is that Excel interop actually opens Excel.exe and iteroperates with the process. You won't be able to remove the overhead of starting Excel, which is probably the bulk of your processing time.
The other part is that for every cell you edit you create a lot of calls "under the hood" to the interop layer. You can vectorize these calls.
For reading:
https://stackoverflow.com/a/42604291/3387223
For writing (VB example):
https://stackoverflow.com/a/23503305/3387223
That way you only create one interop operation for the whole range of values. This will be roughly 25 times quicker than inserting 25 values.
But as I stated above, starting Excel is probably what takes most of your time.
You can read and write Excel sheets faster with OpenXML, but maybe you'll run into some formatting issues, and you won't get instant updates of other formulas in your Excel sheet (if that's what you need).
https://msdn.microsoft.com/en-us/us-en/library/office/bb448854.aspx
Here's an example on generating Excel sheets:
https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx
And if you want an easier time dealing with OpenXml there is ClosedXml:
https://github.com/closedxml/closedxml
Which will make OpenXml about as easy as standard interop.

Related

How to open an excel file and past rest api response that is already in csv format into the new excel?

I fetch from a rest API a response which is already in csv format.
I managed to open an excel file but the silly thing is, I don't find anywhere how to past it without sending everything within the first cell...
So far, I have this code:
//if status is 200201, that means that my csv is generated
// API_Helper is my class, FeedData is my function that fetches the final response
if (statusResponse == "200201")
{
string finalResult = API_Helper.FeedData(FeedJobID, accessT);
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook = xlApp.Workbooks.Add();
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Cells[1, 1] = finalResult;
}
If I use this above code, basically I have all my response within the first cell instead having all my csv populated. I'm trying either having a classic csv format or having my data populated properly into a normal excel using the comma separated.
Does anybody have an idea ? Let me know if you need more info. I'll be please to add complement if needed.

How to store many textboxes and labels in specific rows and columns in Excel?

I have little knowledge in c#. I am making window form where it take some inputs from user then i want to save it in excel file. Like this http://i.stack.imgur.com/PZubD.png
, sorry i can't upload image, so image link is above as you can see i made form which look like this and i want this whole form to save exactly in excel file. All designing and labels and testboxes should be exactly at same place so that it will save data in excel like the image below http://i.stack.imgur.com/8AmMS.png. As you can see quantity and product name and rate and total amount is saved in the belonged places. I want exactly like this that all data store exactly below them. Is it possible to make it happen?
I can save data from windows form to excel but not in this exact format. Thats why i am asking this here.
Please help me.
It is possible to do.
You would need to utilize the Excel Interop namespace, specifically the Microsoft.Office.Interop.Excel namespace.
Documentation is here:
https://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.excel.aspx
It gives the capabilities to write to Excel files, update, alter and so on.
In short, you would assign each cell the specific text or label information that you would want.
For example, you would have in a method something along the lines of:
// Put this in the namespace references sections
using Excel = Microsoft.Office.Interop.Excel;
//inside your class(es) that will be writing to Excel
Excel.Application xlApp; //instance of the Excel application
Excel._Workbook xlWB; //will become the workbook object of the Excel application
Excel._WorkSheet xlWS; //will become the worksheet object of the Excel application
object misval = System.Reflection.Missing.Value; //used to cover certain arguements for saving (as far as I gather)
public void ExcelWriter()
{
xlApp = new Excel.Application; //starts an instance of Excel
xlApp.Visible = false; //hides the application from appearing on screen
xlApp.Dialog = false; //keeps the "Save As" dialogs from appearing when it goes to save
//adds a new workbook to the Excel application and puts a new sheet in it
xlWB = (Excel._Workbook)(xlApp.Workbooks.Add("Name of Book Goes Here"));//your workbook instance
xlWS = (Excel._WorkSheet)xlWS.ActiveSheet;//your worksheet instance
//each cell is referenced along an array
//for example, cell A1 is 1,1
xlWS.Cells[1,1] = label1.Text;
xlWS.Cells[1,2] = label2.Text;
xlWS.Cells[1,3] = label3.Text;
xlWS.Cells[1,4] = label4.Text;
.....
//whatever executable code you'd like here
//formatting of cells, fonts, etc.
xlWB.SaveAs("C:\\Path\Goes\Here", misval, misval, misval,
misval, misval, misval, misval, misval,
misval, misval, misval, misval);
xlWB.Close();
xlApp.Quit();
}
But that leads into a great deal of question such as:
Do you need to open an existing file, create a new one each time, etc?
Do you want the user to verify the Excel page is correct before saving?
Is the Excel formatting extremely important?
Are you making a new worksheet each time? A new workbook?
Is this coming from a template worksheet or building a new one from scratch each time?
I will also say this: the Interops can be VERY finicky with closing applications correctly. If anywhere you are generating errors that cause your app to close or not quit Excel properly, it will leave the Excel instance running. Be sure to make check your Task Manager, check for exceptions, and make sure that Excel exits when its supposed to.
Some other posts to reference:
quitting excel with C# (while using excel automation)
Writing to Excel using C#

Does ClosedXML support setting a worksheet's zoom level?

I am using closedXML to generate an Excel file from C# and I am trying to see if there is anyway to set the zoom level of a worksheet. I can't find this in any of the documentation or from googling?
Does anybody know how to do this?
It's now possible, starting with ClosedXML version 0.87.0, via the IXLSheetView.ZoomScale property.
using Excel = ClosedXML.Excel;
var wb = new Excel.XLWorkbook();
Excel.IXLWorksheet ws = wb.AddWorksheet("zoom");
Excel.IXLSheetView view = ws.SheetView;
/* Value can be set between 10 and 400 */
view.ZoomScale = 85;
You can check the IXLSheetView source code for more information.
Update for version 0.87+: https://stackoverflow.com/a/52755386/2610249
No, ClosedXML does not support setting the zoom. The option that johny links to is only for scaling of the pages when printing.
There is a feature request on the ClosedXML page, but no answer from the developer.
As previously answered, you can't, but I've found a way around it which works well:
Create a template Excel file in advance, with all sheets' zoom levels set to how you want them.
When you create your workbook, instead of:
public XLWorkbook CreateWorkbook()
{
XLWorkbook workbook = new XLWorkbook();
IXLWorksheet worksheet = workbook.AddWorksheet("First sheet");
// ...
return workbook;
}
do this:
public XLWorkbook CreateWorkbookWithZoom()
{
XLWorkbook workbook = new XLWorkbook(#"C:\your template file.xlsx");
IXLWorksheet worksheet = workbook.Worksheet(1);
worksheet.Name = "First sheet";
// ...
return workbook;
}
where C:\your template file.xlsx is the path of your template file.
I think you can also handle having a variable number of sheets, by copying existing (blank) worksheets instead of creating new ones. You can get creative with having different blank template worksheets to choose from, if you need to set the zoom level dynamically.
A pull request for this has been logged at https://github.com/ClosedXML/ClosedXML/pull/180

read/write a simple excel file using c#

I'm trying to find a simple way of writing an excel file in c#, but everything that I've found on thank you for your help.
You have two options available to you
The First is to use Interop Assemblies here is a link to some sample code on how to do that Write Data to Excel using C#
The Second option is to use OLEDB. There is some information on Stack Overflow on that here
Use epplus as mentioned above,It makes it really simple. This is the code for a spread sheet i created with it today.
using (ExcelPackage pck = new ExcelPackage())
{
//Give the worksheet a name
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Inventory as of " + DateTime.Now.ToString("MM/dd/yyyy"));
//dt is a datable that i am turning into an excel document
ws.Cells["A1"].LoadFromDataTable(dt, true);
//Format the header columns(Color,Pattern,etc.)
using (ExcelRange rng = ws.Cells["A1:AA1"])
{
rng.Style.Font.Bold = true;
rng.Style.Fill.PatternType = ExcelFillStyle.Solid; //Set Pattern for the background to Solid
rng.Style.Fill.BackgroundColor.SetColor(Color.FromArgb(79, 129, 189)); //Set color to dark blue
rng.Style.Font.Color.SetColor(Color.White);
}
//End Format the header columns
//Give the file details(ie. filename, etc.)
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=Inventory Report " + DateTime.Now.ToString("MM/dd/yyyy") + ".xlsx");
//Write the file
Response.BinaryWrite(pck.GetAsByteArray());
Response.End();
pck.Save();
}
what you would need is epplus, this will help you to create 2007+ excel file
not compatible with 2003 and under
There is no really easy way depending of the version of excel file you want to write. If you want to go for xls you won't have much options than using Excel interop which would also have the dependency to have Excel installed.
The newer version offers some more options as it is just XML in the background. You can choose yourself how to create it, either yourself, some libraries or again Interop.
If you just want to display a table without any styling, there was (afair) a way to write csv file and excel can open it quite well (depending on the data types you want to use in it).

Slow Performance When Reading Excel

I want to read excel file but in this way is too slow. What pattern should I use to read excel file faster. Should I try csv ?
I am using the following code:
ApplicationClass excelApp = excelApp = new ApplicationClass();
Workbook myWorkBook = excelApp.Workbooks.Open(#"C:\Users\OWNER\Desktop\Employees.xlsx");
Worksheet mySheet = (Worksheet)myWorkBook.Sheets["Sheet1"];
for (int row = 1; row <= mySheet.UsedRange.Rows.Count; row++)
{
for (int col = 1; col <= mySheet.UsedRange.Columns.Count; col++)
{
Range dataRange = (Range)mySheet.Cells[row, col];
Console.Write(String.Format(dataRange.Value2.ToString() + " "));
}
Console.WriteLine();
}
excelApp.Quit();
The reason your program is slow is because you are using Excel to open your Excel files. Whenever you are doing anything with the file you have to do a COM+ interop, which is extremely slow, as you have to pass memory across two different processes.
Microsoft has dropped support for reading .xlsx files using Excel interop. They released the OpenXML library specifically for this reason.
I suggest you use a wrapper library for using OpenXML, since the API is pretty hairy. You can check out this SO for how to use it correctly.
open xml reading from excel file
You're accessing Excel file through excel interop. By doing reads cell by cell you're doing a lot of P/Invoke's which is not very performant.
You can read data in ranges, not cell by cell. This loads the data into memory and you could iterate it much faster. (Eg. try to load column by column.)
BTW: You could use some library instead like http://epplus.codeplex.com which reads excel files directly.
Excel Data Reader
Lightweight and very fast if reading is your only concern.

Categories

Resources