well i have to creat just one excel file and 2 sheets both are fill using a 2 diferent DataTable, it gives the name the user only has to click save, the next code allows me to seend one datatable to one sheet (i am using C#, asp.net, and NOT using Visual Studio, i am writing in the Notepad my code):
string name2="Centroids";
HttpContext context = HttpContext.Current;
context.Response.Clear();
foreach (System.Data.DataRow row in _myDataTable2.Rows)
{
for (int i = 0; i < _myDataTable2.Columns.Count; i++)
{
context.Response.Write(row[i].ToString().Replace(",", string.Empty) + ",");
}
context.Response.Write(Environment.NewLine);
}
context.Response.ContentType = "text2/csv";
context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + name2 + ".csv");
but i have no idea how to creat the second sheet and use the second DataTable, any ideas of how to find a solution, this way the user has only to save and donwload only one document and not save as many DataTable are in the programa
You probably want to explore the possibility of using EPPlus. In my experience, using Response object has lot of constraints and take too much development effort to generate Excel file.
Url:
http://epplus.codeplex.com/
You should use open source libraries for generating native excel files, there is no way you can create two sheets with csv.
Use NPOI (xls) or / and EPPlus (xlsx) and fully control your excel export, in this answer https://stackoverflow.com/a/9569827/351383 you can see example of creating excel file from DataTable with EPPlus. You can edit that method to accept DataTable list and create new sheets for each table, it's simple, just :
ExcelPackage pack = new ExcelPackage();
ExcelWorksheet ws = pack.Workbook.Worksheets.Add(sheetName);
public bool LlenarExcelxlsx(List<DatosEntidad> listaOrigen)
{
bool exito = false;
string[] tipoLista = { "A", "B", "C" };
string nombreArchivo = #"D:\prueba.xlsx";
IWorkbook wb = new XSSFWorkbook();
using (FileStream fileData = new FileStream(nombreArchivo, FileMode.Create, FileAccess.Write))
{
for (int k = 0; k < tipoLista.Length; k++)
{
List<DatosEntidad> listaDestino = listaOrigen
.Where(c => c.tipo == tipoLista[k]).ToList();
DataTable dt = ToDataTable(listaDestino);
ISheet sheetx = wb.CreateSheet("Res_" + tipoLista[k] + k);
ICreationHelper cH = wb.GetCreationHelper();
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow row = sheetx.CreateRow(i);
for (int j = 0; j < 13; j++)
{
ICell cell = row.CreateCell(j);
cell.SetCellValue(cH.CreateRichTextString(dt.Rows[i].ItemArray[j].ToString()));
}
}
}
wb.Write(fileData);
exito = true;
}
return exito;
}
Related
My project has 2 console applications.
First application is writing data to the "first sheet" of an existing excel file (xlsx). The same excel file has a "second sheet" which is pretty huge and is using several formulas which are based on the data of the first sheet.
I am using the following code for writing the data to the first sheet:
public void WriteExcel(string InvoiceNo, string InvoiceDate, ...., int rowNumber)
{
using (ExcelPackage excelPackage = new ExcelPackage(this.excelFilePath))
{
ExcelWorksheet firstWorksheet = excelPackage.Workbook.Worksheets.First();
firstWorksheet.Cells[rowNumber, 1].Value = (rowNumber - 2).ToString();
firstWorksheet.Cells[rowNumber, 2].Value = InvoiceNo;
firstWorksheet.Cells[rowNumber, 3].Value = InvoiceDate;
.
.
excelPackage.Save();
}
}
The above code is working completely fine.
Second application is fetching data from the second sheet of this excel file and here I am facing an strange issue.
The application, in the first place, is not picking up the data from the second sheet. But if I am opening the same excel file and closing it after saving it (by pressing Ctrl + S), then the application is fetching data properly.
I am using the following code to fetch the data:
string FilePath = #"file path";
foreach (string file in Directory.EnumerateFiles(FilePath, "*.xlsx"))
{
FileInfo fileInfo = new FileInfo(file);
ExcelPackage package = new ExcelPackage(fileInfo);
ExcelWorksheet excelSheet = package.Workbook.Worksheets[2];
int colCount = excelSheet.Dimension.End.Column;
int rowCount = excelSheet.Dimension.End.Row;
for (int col = 7; col < colCount; col++)
{
if (excelSheet.Cells[27, col].Value != "" && excelSheet.Cells[27, col].Value != null && excelSheet.Cells[27, col].Value.ToString() != "NAN")
{
Console.WriteLine("Data found!.. " + excelSheet.Cells[27, col].Value);
Console.ReadLine();
}
}
}
Please help me on this.
I am desperately trying to add multiple items from an excel sheet into a listview using c#. I have looked all over the Internet for a working solution but still no result.
I would like to ask anybody who knows about c#'s listview for an helping hand...
Thanks in advance
code so far:-
public void InitializeListView(string path) {
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook sheet = excel.Workbooks.Open(path);
Microsoft.Office.Interop.Excel.Worksheet wx = excel.ActiveSheet as Microsoft.Office.Interop.Excel.Worksheet;
int count = 0;
int row = 0;
int col = 0;
Excel.Range userrange = wx.UsedRange;
count = userrange.Rows.Count;
statusBar1.Panels[1].Text = "Amount: " + count;
for (row = 1; row <= count; row++) {
for (col = 1; col <= 4; col++) {
listView1.Items.Add(wx.Cells[row, col].Value2);
listView1.Items.Add(wx.Cells[row, col].Value2);
listView1.Items.Add(wx.Cells[row, col].Value2);
listView1.Items.Add(wx.Cells[row, col].Value2);
}
}
sheet.Close(true, Type.Missing, Type.Missing);
excel.Quit();
}//------------------ end of InitializeListView -------------------------
This might be help you please see https://www.codeproject.com/Questions/460391/Retrieve-datas-from-Excel-Sheet-to-Listview
This is a simple method. Please look if it helps you.
1. Convert the Excel file in to .csv and Store it in the a Path
2. Take the data from .csv file to list.
3. Delete the .csv file once all data is loaded in List<>.
To Read from .csv
string filepath = "D:\\sample.csv";
var lineCount = File.ReadAllLines(#"D:\\sample.csv").Length;
int TotalLines = Int32.Parse(lineCount.ToString());
StreamReader sr = new StreamReader(filepath);
string line;
List<string> lstSample = new List<string>();
while ((line = sr.ReadLine()) != null)
{
lstSample = line.Split(',').ToList();
}
I want to export my Excel sheet using Excel Interloop...
i have a datatable which i convert it to Excel sheet...
now is there any way to save file using save dialogue box in MVC 4
here my code
public string DataTableToExcel(DataTable dt, string htmlHeading, string key)
{
try
{
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook excelworkBook;
Microsoft.Office.Interop.Excel.Worksheet excelSheet;
Microsoft.Office.Interop.Excel.Range excelCellrange;
excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false;
excelworkBook = excel.Workbooks.Add(Type.Missing);
excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelworkBook.ActiveSheet;
excelSheet.Name = "Sheet1";
DataSet new_ds = new DataSet();
DataTable dtCopy = dt.Copy();
new_ds.Tables.Add(dtCopy);
foreach (DataTable table in new_ds.Tables)
{
for (int i = 1; i < table.Columns.Count + 1; i++)
{
excelSheet.Cells[1, i] = table.Columns[i - 1].ColumnName;
}
for (int j = 0; j < table.Rows.Count; j++)
{
for (int k = 0; k < table.Columns.Count; k++)
{
excelSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString();
}
}
}
///// Now how can i export my Excel in save As box ???
}
You cannot prompt a dialog box to the user because you are on the server side.
You can load the file in a Stream and send it to the client. And it is the client's browser which decide where to save this file.
That said, you have to be aware that Interop running ont the server side is not recommended by Microsoft (see : KB Microsoft Problems using server-side automation of Office)
I have a code to export data from datagridview to Excel sheet but the problem is it is very slow because it is inserting data and formatting each cell.
How can I improve performance of this operation?
Below is my code
public static void ExcelExport(DataGridView Dg, string TypePass)
{
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
ExcelApp.Application.Workbooks.Add(Type.Missing);
Excel_12.ApplicationClass oExcel_12 = null; //Excel_12 Application
Excel_12.Workbook oBook = null; // Excel_12 Workbook
Excel_12.Sheets oSheetsColl = null; // Excel_12 Worksheets collection
Excel_12.Worksheet oSheet = null; // Excel_12 Worksheet
Excel_12.Range oRange = null; // Cell or Range in worksheet
Object oMissing = System.Reflection.Missing.Value;
oExcel_12 = new Excel_12.ApplicationClass();
oExcel_12.UserControl = true;
oBook = oExcel_12.Workbooks.Add(oMissing);
oSheetsColl = oExcel_12.Worksheets;
oSheet = (Excel_12.Worksheet)oSheetsColl.get_Item("Sheet1");
oRange = (Excel_12.Range)oSheet.Cells[1, 1];
oRange.Value2 = "";
oRange.Font.Name = "Tahoma";
oRange.Font.Size = 12;
(oRange).Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White);
(oRange).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Gray);
if (TypePass.Trim().Length > 0)
{
oRange = (Excel_12.Range)oSheet.Cells[2, 1];
oRange.Value2 = TypePass;
oRange.Font.Name = "Tahoma";
oRange.Font.Size = 10;
}
int c = 0;
if (Dg.ColumnHeadersVisible == true)
{
for (int j = 0; j < Dg.Columns.Count; j++)
{
if (Dg.Columns[j].Visible == true)
{
oRange = (Excel_12.Range)oSheet.Cells[4, c + 1];
oRange.Value2 = Dg.Columns[j].HeaderText + " ";
oRange.Font.Bold = true;
oRange.Font.Name = "Tahoma";
oRange.Font.Size = 9;
(oRange).Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White);
(oRange).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Teal);
oExcel_12.Columns.AutoFit();
c++;
}
}
}
c = 0;
for (int i = 0; i < Dg.Rows.Count; i++)
{
for (int j = 0; j < Dg.Columns.Count; j++)
{
if (Dg.Columns[j].Visible == true)
{
oRange = (Excel_12.Range)oSheet.Cells[i + 5, c + 1];
if (Dg[j, i].Value == null)
{
oRange.Value2 = " ";
}
else
{
oRange.Value2 = Dg[j, i].Value.ToString().Replace('\n', ' ') + " ";
}
oRange.Borders.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
oRange.Font.Name = "Tahoma";
oRange.Font.Size = 8;
oExcel_12.Columns.AutoFit();
// oRange.NumberFormat = "dd/MM/yyyy";
c++;
}
}
c = 0;
}
oExcel_12.Visible = true;
oBook = null;
oExcel_12 = null;
GC.Collect();
}
You can use Open XML SDK if you like.
I have used Open XML for export data to Excel spreadsheet (.XLSX format) and i can assure that performances are great.
I can generate 50,000 cell spreadsheet within 2, 3 seconds
1 Million cell spreadsheet within 60 seconds [That's 10,000 Row
100 Column spreadsheet]
What you need to know :
Lean how spreadsheet is structured
Follow given guides here and here
Learn about Styling [kind of PRO level which enables many possibilities]
Work with Open XML Productivity tool ; Will ease your learning curve guide
Advantage :
you can create well formatted Excel sheets without having Office
package installed.
Also you can expand spreadsheet generating even to server side if
you like.
At first you will feel it's hard compared to InterOp , but once you have properly implemented you will be able to use same Excel spreadsheet function for ANY project.!
If you decide to stick in Microsoft.Office.Interop.Excel, you can utilize the code by setting the format and data in range properly.
Set header styles for 1 row
Set content styles from columns * row
Build array from the DataGridView cell values then write it in range is a very quick way: Write Array to Excel Range
Btw, GC.Collect cannot serve the purpose for close the COM object, please reference to Proper disposal of COM interop objects in C# particularly MS Office applications
MS Office Interop is slow and even Microsoft does not recommend Interop usage on server side. For more details see what Microsoft stated on why not to use OLE Automation.
Microsoft Excel released XLSX file format with Office 2007 and recommends the usage of OpenXML SDK instead of Interop.
If you must save Excel files in XLS file format, you can use an Excel library like EasyXLS.
See the following code sample as alternative of exporting DataGridView to Excel:
// Create a DataSet and add the DataTable of DataGridView
DataSet dataSet = new DataSet();
dataSet.Tables.Add((DataTable)dataGridView);//or ((DataTable)dataGridView.DataSource).Copy() to create a copy
// Export Excel file
ExcelDocument workbook = new ExcelDocument();
workbook.easy_WriteXLSFile_FromDataSet(filePath, dataSet,
new EasyXLS.ExcelAutoFormat(EasyXLS.Constants.Styles.AUTOFORMAT_EASYXLS1),
"Sheet1");
For exporting the formatting that you need you can create your own ExcelAutoFormat. Check this code sample on how to export datagridview to Excel in C# with formatting.
How do I export data from my C# console application to Excel using Microsoft.Office.Interop dll?
Add a using statement like this:
using Excel = Microsoft.Office.Interop.Excel;
Then define a variable that will enable you to work with Excel documents and workbooks:
Excel.Application xlApp = new Excel.Application();
Create a function that will write from your DataSet into an Excel document (This is from one of my Windows applications button_click function, but I think you will be able to make the necessary adjustments):
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DataGridViewRow red = dataGridView1.Rows[i];
for (int j = 0; j < red.Cells.Count-2; j++)
{
if (j != 0)
{
xlApp.Cells[i + 1, j + 1] = "'" + Convert.ToString(red.Cells[j].Value);
}
else
{
xlApp.Cells[i + 1, j + 1] = Convert.ToString(red.Cells[j].Value);
}
}
}
xlApp.AutoCorrect.ReplaceText = false;
saveFileDialog1.DefaultExt = ".xls";
saveFileDialog1.FileName = textBox2.Text;
saveFileDialog1.InitialDirectory = "Desktop";
saveFileDialog1.ShowDialog();
try
{
xlApp.ActiveWorkbook.SaveCopyAs(FileName);
}
catch
{
MessageBox.Show("Warning");
}
ImeDatoteke = "";
xlApp.Quit();
As you see, I use DataGridView to display the data that I want to write into the Excel file, but since DataGridView uses DataSets I dont think you will have to much problems to adjust this code