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)
Related
[This is my excel sheet where last column value entered from datagrid is not getting added]
code:
private void writeExcelFileToolStripMenuItem1_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
// creating new WorkBook within Excel application
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
// creating new Excelsheet in workbook
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
// see the excel sheet behind the program
app.Visible = true;
// get the reference of first sheet. By default its name is Sheet1.
// store its reference to worksheet
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
// changing the name of active sheet
worksheet.Name = "Exported from gridview";
// storing header part in Excel
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridView1.Columns[i - 1].HeaderText;
}
// storing Each row and column value to excel sheet
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
//This Filter property is used to filter the type of files to be save
saveFileDialog1.Filter = "Excel Workbook|*.xlsx";
//This is used to open the savedialog window
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
app.Workbooks[1].SaveCopyAs(saveFileDialog1.FileName);
MessageBox.Show("Excel Saved", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
//TextBoxForMultipleSelctionOfExcel.Text = "";
}
//Closing the Workbook
for (int i = 1; i <= app.Workbooks.Count; i++)
{
app.Workbooks[i].Close(0);
}
//Quiting the Excel Application
app.Quit();
I'm trying to export data from my web-application to Excel
This is my class ExcelExport
using Excel = Microsoft.Office.Interop.Excel;
public static class ExcelExport
{
public static void ExportDataTableToExcel(DataTable table, string filePath, bool overwrite = false)
{
if (File.Exists(filePath))
{
if (overwrite)
File.Delete(filePath);
else return;
}
Excel.Application excelApp = new Excel.Application();
Excel.Workbook excelWorkBook = excelApp.Workbooks.Add();
Excel.Worksheet excelWorkSheet = excelWorkBook.Sheets.Add();
excelWorkSheet.Name = table.TableName;
for (int i = 1; i < table.Columns.Count + 1; i++)
excelWorkSheet.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++)
excelWorkSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString();
excelWorkBook.SaveAs(filePath);
excelWorkBook.Close();
excelApp.Quit();
}
public static void Main(string[] args)
{
DataTable table = new DataTable("test");
table.Columns.AddRange(
new []
{
new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string))
}
);
DataRow row = table.NewRow();
row["Id"] = 1;
row["Name"] = "Me";
table.Rows.InsertAt(row, 1);
ExportDataTableToExcel(table, #"c:\temp\bla.xlsx", true);
}
}
As you can see, there is also a Main-method. When I try to run this as console-application, this works fine.
When I run this in my web-application (calling the same function with same parameters, even calling the Main()) I'm getting following exception at the excelWorkBook.SaveAs(filePath);:
System.Runtime.InteropServices.COMException: "Exception from HRESULT: 0x800A03EC"
Any idea what could go wrong? Or you know any workarounds?
I found a solution to make this work:
Instead of SaveAs you can use excelWorkBook.SaveCopyAs(filePath); and it works.
Not sure why this works in another way/better than SaveAs, but it works.
Im using Visual Studio to create an automated test that creates two excel sheets. As a final check, I need to compare the content of these two excel sheets and ensure that they are equal. Is there any way to do this with assertions?
Something like Assert.AreEqual(file1, file2);?
Any help or guidance would be appreciated!
Thanks to Mangist for guidance on this. Ive written the following to compare two excel files:
public bool compareFiles(string filePath1, string filePath2)
{
bool result = false;
Excel.Application excel = new Excel.Application();
//Open files to compare
Excel.Workbook workbook1 = excel.Workbooks.Open(filePath1);
Excel.Workbook workbook2 = excel.Workbooks.Open(filePath2);
//Open sheets to grab values from
Excel.Worksheet worksheet1 = (Excel.Worksheet)workbook1.Sheets[1];
Excel.Worksheet worksheet2 = (Excel.Worksheet)workbook2.Sheets[1];
//Get the used range of cells
Excel.Range range = worksheet2.UsedRange;
int maxColumns = range.Columns.Count;
int maxRows = range.Rows.Count;
//Check that each cell matches
for (int i = 1; i <= maxColumns; i++)
{
for (int j = 1; j <= maxRows; j++)
{
if (worksheet1.Cells[j, i].Value == worksheet2.Cells[j, i].Value)
{
result = true;
}
else
result = false;
}
}
//Close the workbooks
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(range);
Marshal.ReleaseComObject(worksheet1);
Marshal.ReleaseComObject(worksheet2);
workbook1.Close();
workbook2.Close();
excel.Quit();
Marshal.ReleaseComObject(excel);
//Tell us if it is true or false
return result;
}
And using an assertion to check result:
Assert.IsTrue(compareFiles(testFile, compareFile), "Output files do not match.");
Can you convert the expected/actual Excel sheets to a text format, such as CSV?
If so, you could use Approval Tests instead. This allows you to have a text file as your "expected" test result. When tests fail it can show you the actual result of the test, diff'd against the expected result.
Screenshot taken from this review of Approval Tests.
One Option will be using Open source library called as EPPlus. You can download and refer it in you automated test application. EPPlus gives you multiple ways to read an excel file and compare. One such option is C# Datatable. Here is a sample code..
public static DataTable GetDataTableFromExcel(string path, bool hasHeader = true)
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
DataRow row = tbl.Rows.Add();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
}
return tbl;
}
}
For both the Excel files , same process can be adopted, and it will give you the desired results.
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;
}
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