how to write data to Excel without changing the current format - c#

I am trying to overwrite data in excel sheet. The way I do it is by deleting the content from the the sheet and then writing range of data. The problem is when I write the data it deletes the cell format and then places my numbers as text.
is there a way to keep the format which the user has defined so when I write data it uses the same format?

You can Use the Microsoft.Office.Interop.Excel dll file. Add it in your project reference and in your Code as Using using Excel = Microsoft.Office.Interop.Excel;
Then check the below code. Also to you this dll there should be Microsoft Excel Installed in the machine where this code is going to run.
Excel.Application excel = new Excel.Application();
excel.DisplayAlerts = false;
excel.Workbooks.Add();
Excel.Worksheet worksheet = excel.ActiveSheet;
int rowIndex = 2 ;
worksheet.Cells[1, "A"] = "List Title";
worksheet.Cells[1, "B"] = "Item Count";
Console.WriteLine("Copying the contents to Excel");
foreach (var list in listCollection)
{
worksheet.Cells[rowIndex, "A"] = list.Title;
worksheet.Cells[rowIndex, "B"] = list.ItemCount;
rowIndex++;
//Console.Write("List Title: {0}", list.Title);
//Console.WriteLine("\t"+"Item Count:"+list.ItemCount);
}
string fileName = string.Format(#"C:\FileName.xlsx");
worksheet.SaveAs(fileName);
Console.WriteLine("Export Completed");
Console.ReadLine();
excel.Quit();
GC.Collect();

Related

Insert into Existing excel file using EPP on C#

I want to insert value on my excel ,but i have a problem when i run my application, its create a new file excel ,doesnt insert value into existing file,
using (ExcelPackage excel = new ExcelPackage())
{
excel.Workbook.Worksheets.Add("Worksheet1");
// Target a worksheet
var worksheet = excel.Workbook.Worksheets["Worksheet1"];
worksheet.Cells[1, 1].Value = "Name";
worksheet.Cells[2, 1].Value = "ID";
FileInfo excelFile = new FileInfo(#"E:\ExcelTest.xls");
excel.SaveAs(excelFile);
I want my Program insert into existing file ,not create a new one,
how i can solve this?
The EPPlus Wiki Getting Started covered this exact scenario.
FileInfo excelFile = new FileInfo(#"E:\ExcelTest.xls");
using (ExcelPackage excel = new ExcelPackage(excelFile))
{
// Target a worksheet
var worksheet = excel.Workbook.Worksheets["Worksheet1"];
worksheet.Cells[1, 1].Value = "Name";
worksheet.Cells[2, 1].Value = "ID";
excel.Save();
}

How to write to excel c#

I am using this code to write data to excel file.
Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application();
excelapp.Visible = true;
I am using this code to write to excel.
_Workbook workbook = (_Workbook)(excelapp.Workbooks.Open(#"C:\Path\To\Your\WorkBook\ExcelWorkBook.Xls"));
_Worksheet worksheet = (_Worksheet)workbook.ActiveSheet;
worksheet.Cells[1, 1] = "Name";
worksheet.Cells[1, 2] = "Bid";
worksheet.Cells[2, 1] = txbName.Text;
worksheet.Cells[2, 2] = txbResult.Text;
excelapp.Visible = false;
This code works fine except that it works very slowly. I want a fastest way to write tot excel. If I run a loop to write to excel to write thousands of rows, then it works to slowly. Is there any faster way to write the data to excel file like write a whole datatable to excel file of write datatable rows simultaneously rather than cell by cell ?
Try inserting an array to the excel instead:
object[,] arr = new object[rowCount, columnCount];
//Assign your values here
Excel.Range c1 = (Excel.Range)worksheet.Cells[0, 1];
Excel.Range c2 = (Excel.Range)worksheet.Cells[rowCount - 1, columnCount];
Excel.Range range = wsh.get_Range(c1, c2);
range.Value = arr;
Writing / Reading values to / from each cell is far too slow and will consume a lot of time, try doing it in memory.

transfer from c# to excel with multiple sheets

I have a few different dictionaries with different categories of information and I need to output them all into an xls or csv file with multiple spreadsheets. Currently, I have to download each excel file for a specific date range individually and then copy and paste them together so they're on different sheets of the same file. Is there any way to download all of them together in one document? Currently, I use the following code to output their files:
writeCsvToStream(
organize.ToDictionary(k => k.Key, v => v.Value as IacTransmittal), writer
);
ms.Seek(0, SeekOrigin.Begin);
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.AddHeader("Content-Length", ms.Length.ToString());
Response.ContentType = "application/octet-stream";
ms.CopyTo(Response.OutputStream);
Response.End();
where writeCsvToStream just creates the text for the individual file.
There are some different options you could use.
ADO.NET Excel driver - with this API you can populate data into Excel documents using SQL style syntax. Each worksheet in the workbook is a table, each column header in a worksheet is a column in that table etc.
Here is a code project article on the exporting to Excel using ADO.NET:
http://www.codeproject.com/Articles/567155/Work-with-MS-Excel-and-ADO-NET
The ADO.NET approach is safe to use in a multi-user, web app environment.
Use OpenXML to export the data
OpenXML is a schema definition for different types of documents and the later versions of Excel (the ones that use .xlsx, .xlsm etc. instead of just .xls) use this format for the documents. The OpenXML schema is huge and somewhat cumbersome, however you can do pretty much anything with it.
Here is a code project article on exporting data to Excel using OpenXML:
http://www.codeproject.com/Articles/692121/Csharp-Export-data-to-Excel-using-OpenXML-librarie
The OpenXML approach is safe to use in a multi-user, web app environment.
A third approach is to use COM automation which is the same as programmatically running an instance of the Excel desktop application and using COM to control the actions of that instance.
Here is an article on that topic:
http://support.microsoft.com/kb/302084
Note that this third approach (office automation) is not safe in a multi-user, web app environment. I.e. it should not be used on a server, only from standalone desktop applications.
If you're open to learning a new library, I highly recommend EPPlus.
I'm making a few assumptions here since you didn't post much code to translate, but an example of usage may look like this:
using OfficeOpenXml;
using OfficeOpenXml.Style;
public static void WriteXlsOutput(Dictionary<string, IacTransmittal> collection) //accepting one dictionary as a parameter
{
using (FileStream outFile = new FileStream("Example.xlsx", FileMode.Create))
{
using (ExcelPackage ePackage = new ExcelPackage(outFile))
{
//group the collection by date property on your class
foreach (IGrouping<DateTime, IacTransmittal> collectionByDate in collection
.OrderBy(i => i.Value.Date.Date)
.GroupBy(i => i.Value.Date.Date)) //assuming the property is named Date, using Date property of DateTIme so we only create new worksheets for individual days
{
ExcelWorksheet eWorksheet = ePackage.Workbook.Worksheets.Add(collectionByDate.Key.Date.ToString("yyyyMMdd")); //add a new worksheet for each unique day
Type iacType = typeof(IacTransmittal);
PropertyInfo[] iacProperties = iacType.GetProperties();
int colCount = iacProperties.Count(); //number of properties determines how many columns we need
//set column headers based on properties on your class
for (int col = 1; col <= colCount; col++)
{
eWorksheet.Cells[1, col].Value = iacProperties[col - 1].Name ; //assign the value of the cell to the name of the property
}
int rowCounter = 2;
foreach (IacTransmittal iacInfo in collectionByDate) //iterate over each instance of this class in this igrouping
{
int interiorColCount = 1;
foreach (PropertyInfo iacProp in iacProperties) //iterate over properties on the class
{
eWorksheet.Cells[rowCounter, interiorColCount].Value = iacProp.GetValue(iacInfo, null); //assign cell values by getting the value of each property in the class
interiorColCount++;
}
rowCounter++;
}
}
ePackage.Save();
}
}
}
Thanks for the ideas! I was eventually able to figure out the following
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbook ExcelWorkBook = null;
Excel.Worksheet ExcelWorkSheet = null;
ExcelApp.Visible = true;
ExcelWorkBook = ExcelApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
List<string> SheetNames = new List<string>()
{ "Sheet1", "Sheet2", "Sheet3", "Sheet4", "Sheet5", "Sheet6", "Sheet7"};
string [] headers = new string []
{ "Field 1", "Field 2", "Field 3", "Field 4", "Field 5" };
for (int i = 0; i < SheetNames.Count; i++)
ExcelWorkBook.Worksheets.Add(); //Adding New sheet in Excel Workbook
for (int k = 0; k < SheetNames.Count; k++ )
{
int r = 1; // Initialize Excel Row Start Position = 1
ExcelWorkSheet = ExcelWorkBook.Worksheets[k + 1];
//Writing Columns Name in Excel Sheet
for (int col = 1; col < headers.Length + 1; col++)
ExcelWorkSheet.Cells[r, col] = headers[col - 1];
r++;
switch (k)
{
case 0:
foreach (var kvp in Sheet1)
{
ExcelWorkSheet.Cells[r, 1] = kvp.Value.Field1;
ExcelWorkSheet.Cells[r, 2] = kvp.Value.Field2;
ExcelWorkSheet.Cells[r, 3] = kvp.Value.Field3;
ExcelWorkSheet.Cells[r, 4] = kvp.Value.Field4;
ExcelWorkSheet.Cells[r, 5] = kvp.Value.Field5;
r++;
}
break;
}
ExcelWorkSheet.Name = SheetNames[k];//Renaming the ExcelSheets
}
//Activate the first worksheet by default.
((Excel.Worksheet)ExcelApp.ActiveWorkbook.Sheets[1]).Activate();
//Save As the excel file.
ExcelApp.ActiveWorkbook.SaveCopyAs(#"out_My_Book1.xls");

How to display a progressbar when export data into a file in c# wpf

**I have finished the part of export data from database into file,but i find it takes a very very long time to wait for this action finish sometimes.So i want to add a progress bar in my program, but here is my question:
i don't know how big the xx.xls file it is
i don't know how to get the stage of the file size that had been exported
So i don't have any idea about how to compute the percentage of the progress bar. what should i do to get all the information i need or is there any other solutions?
thanks a lot here is my code of export data:**
SaveFileDialog savefiledialog = new SaveFileDialog();
savefiledialog.FileName = #"data.xlsx";
if (!(bool)savefiledialog.ShowDialog())
return;
DbHelper dh = new DbHelper("data.mdb");
ApplicationClass excel = new ApplicationClass();
Workbooks workbooks = excel.Workbooks;
Workbook workbook = workbooks.Add();
Worksheet sheet1 = (Worksheet)excel.ActiveSheet;
ArrayList itemList = dh.setTable("Item").where("1=1").select();
sheet1.Cells[1, "A"] = "col1";
sheet1.Cells[1, "B"] = "col2";
sheet1.Cells[1, "C"] = "col3";
int i = 2;
foreach (Item item in itemList)
{
sheet1.Cells[i, "A"] = item.Website;
sheet1.Cells[i, "B"] = item.Shop_id;
sheet1.Cells[i, "C"] = item.Title;
i++;
}
sheet1.Range["A1"].AutoFormat(Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic1);
string fileName = string.Format(savefiledialog.FileName, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory));
// Save this data as a file
System.Action<string, string, string, string, string, string, string, string, string, string> action = sheet1.SaveAs;
BackgroundWorker b = new BackgroundWorker();
sheet1.SaveAs(fileName);
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.FinalReleaseComObject(sheet1);
workbook.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(workbooks);
excel.Quit();
You can go with table rows count or just show an indeterminate state saying this would take several minutes. Have you tried Bulk Copy ? this will make your export much faster.

How to merge two Excel workbook into one workbook in C#?

Let us consider that I have two Excel files (Workbooks) in local. Each Excel workbook is having 3 worksheets.
Lets say WorkBook1 is having Sheet1, Sheet2, Sheet3
Workbook2 is having Sheet1, Sheet2, Sheet3.
So here I need to merge these two excel workbook into one and the new excel workbook that is let's say Workbook3 which will have total 6 worksheets (combination of workbook1 and workbook2).
I need the code that how to perform this operation in c# without using any third party tool. If the third party tool is free version then its fine.
An easier solution is to copy the worksheets themselves, and not their cells.
This method takes any number of excel file paths and copy them into a new file:
private static void MergeWorkbooks(string destinationFilePath, params string[] sourceFilePaths)
{
var app = new Application();
app.DisplayAlerts = false; // No prompt when overriding
// Create a new workbook (index=1) and open source workbooks (index=2,3,...)
Workbook destinationWb = app.Workbooks.Add();
foreach (var sourceFilePath in sourceFilePaths)
{
app.Workbooks.Add(sourceFilePath);
}
// Copy all worksheets
Worksheet after = destinationWb.Worksheets[1];
for (int wbIndex = app.Workbooks.Count; wbIndex >= 2; wbIndex--)
{
Workbook wb = app.Workbooks[wbIndex];
for (int wsIndex = wb.Worksheets.Count; wsIndex >= 1; wsIndex--)
{
Worksheet ws = wb.Worksheets[wsIndex];
ws.Copy(After: after);
}
}
// Close source documents before saving destination. Otherwise, save will fail
for (int wbIndex = 2; wbIndex <= app.Workbooks.Count; wbIndex++)
{
Workbook wb = app.Workbooks[wbIndex];
wb.Close();
}
// Delete default worksheet
after.Delete();
// Save new workbook
destinationWb.SaveAs(destinationFilePath);
destinationWb.Close();
app.Quit();
}
Edit: notice that you might want to Move method instead of Copy in case you have dependencies between the sheets, e.g. pivot table, charts, formulas, etc. Otherwise the data source will disconnect and any changes in one sheet won't effect the other.
Here's a working sample that joins two books into a new one, hope it will give you an idea:
using System;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
namespace MergeWorkBooks
{
class Program
{
static void Main(string[] args)
{
Excel.Application app = new Excel.Application();
app.Visible = true;
app.Workbooks.Add("");
app.Workbooks.Add(#"c:\MyWork\WorkBook1.xls");
app.Workbooks.Add(#"c:\MyWork\WorkBook2.xls");
for (int i = 2; i <= app.Workbooks.Count; i++)
{
int count = app.Workbooks[i].Worksheets.Count;
app.Workbooks[i].Activate();
for (int j=1; j <= count; j++)
{
Excel._Worksheet ws = (Excel._Worksheet)app.Workbooks[i].Worksheets[j];
ws.Select(Type.Missing);
ws.Cells.Select();
Excel.Range sel = (Excel.Range)app.Selection;
sel.Copy(Type.Missing);
Excel._Worksheet sheet = (Excel._Worksheet)app.Workbooks[1].Worksheets.Add(
Type.Missing, Type.Missing, Type.Missing, Type.Missing
);
sheet.Paste(Type.Missing, Type.Missing);
}
}
}
}
}
You're looking for Office Autmation libraries in C#.
Here is a sample code to help you get started.
System.Data.Odbc.OdbcDataAdapter Odbcda;
//CSV File
strConnString = "Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + SourceLocation + ";Extensions=asc,csv,tab,txt;Persist Security Info=False";
sqlSelect = "select * from [" + filename + "]";
System.Data.Odbc.OdbcConnection conn = new System.Data.Odbc.OdbcConnection(strConnString.Trim());
conn.Open();
Odbcda = new System.Data.Odbc.OdbcDataAdapter(sqlSelect, conn);
Odbcda.Fill(ds, DataTable);
conn.Close();
This would read the contents of an excel file into a dataset.
Create multiple datasets like this and then do a merge.
Code taken directly from here.

Categories