I have a regular html table:
<table>
<tr>hello</tr>
<tr>world</tr>
</table>
and I am creating an XLS file out of it:
string randomname = #"C:\attachmentsfolder\" + System.IO.Path.GetRandomFileName() + ".xls";
System.IO.File.WriteAllText( randomname, message);
When I open the XLS file generated, I need to MANUALLY expand the columns in order to see long data.
My question is: How can I generate this XLS file such that the columns are already sized properly?
You could do that easily with EPPlus (Open Source .NET Excel 2007+ library), and you will have a valid excel file, here is the example code :
public static void FitAndSaveToExcel(FileInfo excelFile, string sheetName)
{
ExcelPackage pack = new ExcelPackage();
ExcelWorksheet ws = pack.Workbook.Worksheets.Add(sheetName);
ws.Cells[1, 1].Value = "Some Long text that needs fitting!";
ws.Cells[1, 2].Value = "Short one";
ws.Column(1).AutoFit();
pack.SaveAs(excelFile);
}
In Excel VBA, you can achieve the effect you seek with Rng.Columns.AutoFit. I believe the C# equivalent is Rng.Columns.AutoFit();.
However, I agree with Diodeus, you will have to fix your html first.
You also could use a third-party tool like e.g. Aspose.Cells to create the Excel file.
I've used this in a lot of projects successfully. It provides the auto-fit function that you require.
Related
I am using the Syncfusion.XlsIO.WinForms dependency to develop with C# but when generating a file a sheet is generated that says "Created with a trial version of Syncfusion Essential XlsIO" so I think it is paid. I have been looking for a free NuGet package to modify an excel file however many dependencies remove objects like macros and textboxes on save with a function like SaveAs or Save (Macros and textboxes are part of the document). excel and I don't generate them by code, they belong to the file). I have been using a free option like ClosedXML but it deletes the elements, I have been using this code:
XLWorkbook workbook = XLWorkbook.OpenFromTemplate("C://template//from123.xlsx");
var hoja = workbook.Worksheets.Worksheet(1).Worksheet;
hoja.Cell("B11").Value = "5";
//hoja.Cell("CN").Style.Fill.SetBackgroundColor(XLColor.Black);
workbook.SaveAs(#"C://template" + "//" + "XMLCopy" + ".xlsx");
The result is as follows:
Before modifying the file
After modifying the file with c# and closedXml and saving
Do you know how I can make a modification for free and without deleting my elements?
You should open the original excel file by creating a new workbook object, modify it and then save it as a new file:
using (XLWorkbook workbook = new XLWorkbook("C://template//from123.xlsx"))
{
var hoja = workbook.Worksheets.Worksheet(1);
hoja.Cell("B11").Value = "5";
//hoja.Cell("CN").Style.Fill.SetBackgroundColor(XLColor.Black);
workbook.SaveAs(#"C://template" + "//" + "XMLCopy" + ".xlsx");
}
I have a C# application which purpose is to store a big amount of data. I am using Microsoft.Office.Interop.Excel (Microsoft.Office.Interop.Excel.dll Version 14.0.0.0) to help me accomplish this. I have Excel 2007 installed.
I use the following lines:
excelApp = new Microsoft.Office.Interop.Excel.Application();
excelWorkBook = excelApp.Workbooks.Add(misValue);//*--------> LINE NOT WORKING */
excelWorksheetBeingWritten = (Excel.Worksheet)excelWorkBook.Worksheets.get_Item(1);
My code then iterates through a big list of objects, and each time a row must be written I do something like:
var startCell = excelWorksheetBeingWritten.Cells[excelLineCounter, 1];
var endCell = excelWorksheetBeingWritten.Cells[excelLineCounter, 2];
string[] tmpArray = new string[2] { stringVar1, stringVar2 };
tmpRange = excelWorksheetBeingWritten.Range[startCell, endCell];
tmpRange.Value = tmpArray;
When excelLineCounter exceeds 65536, the "HRESULT: 0x800A03EC exception" is thrown. I am perfectly aware of the (in)famous pre-Excel2007 row limit (which is precisely 65536). What I don't understand is why the interops are using that limit, when Excel 2007 (my version) has a documented limit of 1.048.576 rows.
On the other hand, if I replace the above "LINE NOT WORKING" by the following, it seems to use the Excel 2007 row limit, and the exception vanishes:
excelWorkBook = excelApp.Workbooks.Open(#"H:\Workbook1.xlsx");//*--------> LINE WORKING */
Note: "Workbook1.xlsx" is an empty workbook previously saved as "Excel Workbook (*.xlsx)"
Can someone please tell me what kind of sorcery do I need to do in order to configure the Excel Interop objects to use the Excel 2007 limits by default, preferably without having a previously saved empty .xlsx file laying around?
I encountered a similar issue yesterday and the solution is to change your Excel settings to create xlsx files by default.
In Excel: File -> Options -> Save -> Save files in this format
Your default is probably 'Excel 97-2003 (*.xls)' like mine was. If you change it to 'Excel Workbook (*.xlsx)', your code will work.
Is there any easy to implement library that can be used to read excel files and may be create them later on?
is this my best bet?
http://support.microsoft.com/kb/302084
Try this: http://epplus.codeplex.com
EPPlus is a .net library that reads and writes Excel 2007/2010 files
using the Open Office Xml format (xlsx).
If you are willing to commit yourself to a later version of Excel (2007+) you can also take a look at the OpenXML SDK. It's free, doesn't tie you to having MS Office installed on the machine it will be running on and there are quite a few resources available on how to use it online (including blogs from the OpenXML team).
There is excel package plus:
http://epplus.codeplex.com/
Only works on xlsx though, but Office 2003 is cycling out anyway.
You can use ExcelLibrary ,Although it works for .xls only which is 2003 format
The aim of this project is provide a native .NET solution to create, read and modify Excel files without using COM interop or OLEDB connection.
I had a chance of using EPPLUS ,it was wonderful :) ,It works for new excel format .xlsx which is used in 2007/2010
EPPlus is a .net library , you can read and write to excel files ,create charts ,pictures ,shapes... and Much more
Also take a look at this SO post
I've used oledb, interop and just started using Epplus. So far epplus is proving to be simplest.
http://epplus.codeplex.com/
However, I just posted a problem I have with epplus, but I posted some code you could use as reference.
c# epplus error Removed Part: Drawing shape
I like to use ExcelDataReader for reading and the aforementioned EPPlus for writing. Here's an example.
Here's an example of reading with it:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
// Reading from a binary Excel file ('97-2003 format; *.xls)
// IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
// 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 cdm = new ValueSetRepository();
for (int i = 0; i < result.Tables.Count; i++)
{
// CHECK if tableNames filtering is specified
if (tableNames != null)
{
// CHECK if a table matches the specified tablenames
var tablename = result.Tables[i].TableName;
if (!tableNames.Contains(tablename))
{
continue;
}
}
var lookup = new ValueSetLookup();
lookup.CmsId = result.Tables[i].Rows[2][0].ToString();
lookup.NqfNumber = result.Tables[i].Rows[2][1].ToString();
lookup.Data = new List<ValueSetAttribute>();
int row_no = 2;
while (row_no < result.Tables[i].Rows.Count) // i is the index of table
// (sheet name) which you want to convert to csv
{
var currRow = result.Tables[i].Rows[row_no];
var valueSetAttribute = new ValueSetAttribute()
{
Id = currRow[0].ToString(),
Number = currRow[1].ToString(),
tName = currRow[2].ToString(),
Code = currRow[7].ToString(),
Description = currRow[8].ToString(),
};
lookup.Data.Add(valueSetAttribute);
row_no++;
}
cdm.AddRecord(lookup);
A company I used to work for did a lot of research on this and decided a product by SoftArtisans was their best bet:
OfficeWriter
I always found it strange how weak the support for Excel reading and writing was. I'm pretty sure that if you use Microsoft's libraries you have to have Excel installed anyway which is an extra expense just like OfficeWriter.
You could either go for VBA or use the free library from FileHelpers. If you are planning to buy some commerical solutions, I would recommend ASPOSE
According to this website you need to include a reference to the Microsoft Excel 12.0 Object library. From there, you need to do a few things to open up the file. There's a code sample on the website.
PS - Sorry it's not too detailed but I couldn't find the Microsoft Office developer reference with more details.
I used ExcelLibrary with very great results! (until now it support Excel 2003 or lower versions).
http://code.google.com/p/excellibrary/
Yes, multiple open-source libraries exist to help read and/or write Excel spreadsheets using C#.
Here is a shortlist of C# libraries:
Microsoft.Office.Interop.Excel
ExcelDataReader
NPOI
ExcelMapper - NPOI extension
EPPlus
An up-to-date curated list is maintained here.
Example: Reading Excel File using ExcelMapper
a. Install using NuGet, by running below command in NuGet Packet Manager:
Install-Package ExcelMapper
b. Sample C# Code for ExcelMapper
public void ReadExcelUsingExcelMapperExtension()
{
string filePath = #"C:\Temp\ListOfPeople.xlsx";
var people = new ExcelMapper(filePath).Fetch<Person>().ToList();
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Disclaimer: I like the conciseness of ExcelMapper, therefore included sample code for this package. To do the same using other libraries, requires a lot more code.
I have some data in c#, and I want to put this data into Excel. I figure the easiest way is to export it as XML since Excel reads xml files.
What's the easiest way to do this? I don't know what format the xml needs to be in for Excel to read it. I want a simple table of data (headers, data, and totals, although the totals I can simply generate in c# rather than have excel do it).
There might also be a better way without using xml, but simplest is best and definitely no 3rd party stuff...
Ideas?
The easiest way is to dump data into a CSV format, and open it with Excel!
This can take 10 lines of code in Python.
I am sure you can figure this out:
http://en.wikipedia.org/wiki/Comma-separated_values
There's a nice intro at http://www.codeproject.com/KB/office/excelxmlspreadsheet.aspx that should get you started writing basic XML spreadsheets.
You may want to reconsider using 3rd party tools; there are some nice ones out there with good licenses that will make your life a lot easier.
I've used http://www.carlosag.net/Tools/ExcelXmlWriter/ previously to write simple data to an Excel spreadsheet. It outputs right into the Excel XML format you mention.
I've also had success using Apache POI HSSF, though not its most recent incarnation (it lacked Office 2007 support at the time). You can use IKVM to recompile the Java library into a .NET library, and you're good to go.
This article explains how to open an manipulate XML data in Excel 2003, and this video explains the same for 2007.
Or, as lpthnc has suggested, you can export the data as CSV which Excel has no problem handling.
Write a CSV reader writer if you want a good compromise between human and machine readable in a Windows environment
Loads into Excel too.
There's a discussion about it here:
http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.html
That is a C# article not a C one.
An alternate approach if your needs are basic: you can put it into HTML with a table representing your spreadsheet and just name your html file .xls. That way you don't need to worry about what a comma will do to you and can provide a basic level of formatting as well.
I have had to do similar things in the past. The easiest way I have found to do it is to export directly from my application to excel:
Microsoft.Office.Interop.Excel
Populate a datatable, datagrid, dataset, etc. and iteerate through the results and output to excel. The exmaple below is in VB but can be easily altered for your purposes and uses a dataset:
Public Sub ExcelExport(ByVal objDataSet As System.Data.DataSet)
Try
Dim l_ofd As New SaveFileDialog
l_ofd.Filter = "Microsoft 2007 Excel File (*.xls)|*.xls"
If (l_ofd.ShowDialog = System.Windows.Forms.DialogResult.OK) Then
If (objDataSet.Tables.Count > 0) Then
Dim myExcel As ApplicationClass = New ApplicationClass()
myExcel.Visible = _ShowWorkBook
Dim wb1 As Workbook = myExcel.Workbooks.Add("")
Dim ws1 As Worksheet = CType(wb1.Worksheets.Add, Microsoft.Office.Interop.Excel.Worksheet)
ws1.Name = _WorkSheetName
For indx As Integer = 0 To objDataSet.Tables(_DataSetName).Columns.Count - 1
ws1.Cells(1, indx + 1) = objDataSet.Tables(_DataSetName).Columns.Item(indx).ToString
Next
Dim rowID As Integer = 2
Dim dr As DataRow
For Each dr In objDataSet.Tables(_DataSetName).Rows
Dim colID As Integer = 1
Dim data As Object
For Each data In dr.ItemArray
ws1.Cells(rowID, colID) = data.ToString()
colID += 1
Next
rowID += 1
Next
Dim fileName As String = l_ofd.FileName
wb1.SaveAs(fileName)
wb1.Close()
myExcel.Workbooks.Close()
myExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel)
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws1)
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb1)
ws1 = Nothing
wb1 = Nothing
myExcel = Nothing
Else
MessageBox.Show("No data present to export")
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
End Sub
Here's an article that presents another approach using the OpenXML SDK 2.0:
http://openxmldeveloper.org/articles/7937.aspx
It demonstrates the use of ExtremeML - a 100% managed code extension library that greatly simplifies the programmatic creation of Excel content from .NET languages. The tutorial series covers a broad range of scenarios.
Disclaimer: I am the creator of ExtremeML.
if you have a DataTable, I just wrote some code to transfer it to Excel. First you need an Excel reference.
//Just a test DataTable
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.AddRange(new DataColumn[] { new DataColumn("Col1"),new DataColumn("Col2") });
table.Rows.Add("row1col1", "row1col2");
table.Rows.Add("row2col1", "row2col2");
//create Excel Application
Microsoft.Office.Interop.Excel.ApplicationClass s = new ApplicationClass();
Workbook w = s.Workbooks.Add(""); //create new Workbook
Worksheet ws = w.ActiveSheet as Worksheet; //get active sheet.
//COPY COLUMN HEADERS
int startCol = 1;
int startRow = 1;
foreach (DataColumn col in table.Columns)
{
//copy columns in the first row
((Range)ws.Cells[startRow, startCol]).Value2 = col.ColumnName;
startCol++;
}
//COPY ROWS
startRow = 2; //start 2nd row
foreach (DataRow row in table.Rows)
{
startCol = 1;
foreach (DataColumn col in table.Columns)
{
((Range)ws.Cells[startRow, startCol]).Value2 = row[col].ToString();
startCol++;
}
startRow++;
}
//start EXCEL
s.Visible = true;
How to create and download excel document using asp.net ?
The purpose is to use xml, linq or whatever to send an excel document to a customer via a browser.
Edit : Use case
The customer load a gridview ( made with ajax framework ) in a browser, the gridview is directly linked to an sql database.
I put a button 'export to excel' to let customer save this gridview data on his computer ansd i would like to launch a clean download of an excel.
The solutions proposed here are not clean, like send an html document and change the header to excel document etc, i'm searching a simple solution on codeplex right now, i will let you know.
Starter kit
First i have downloaded the Open XML Format SDK 2.0.
It comes with 3 useful tools in :
C:\Program Files\Open XML Format SDK\V2.0\tools
DocumentReflector.exe wich auto
generate the c# to build a
spreadsheet from the code.
OpenXmlClassesExplorer.exe display
Ecma specification and the class
documentation (using an MSDN style
format).
OpenXmlDiff.exe graphically compare
two Open XML files and search for
errors.
I suggest anyone who begin to rename .xlsx to .zip, so you can see the XML files who drive our spreadsheet ( for the example our sheets are in "xl\worksheets" ).
The code
Disclaimer : I have stolen all the code from an MSDN technical article ;D
The following code use an *.xlsx template i made manually to be able to modify it.
Namespaces references
using System.IO;
using System.Xml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
// Database object
DataClassesDataContext db = new DataClassesDataContext();
// Make a copy of the template file.
File.Copy(#"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\livreurs.xlsx", #"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\generated.xlsx", true);
// Open the copied template workbook.
using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(#"C:\inetpub\wwwroot\project.Web\Clients\Handlers\oxml-tpl\generated.xlsx", true))
{
// Access the main Workbook part, which contains all references.
WorkbookPart workbookPart = myWorkbook.WorkbookPart;
// Get the first worksheet.
WorksheetPart worksheetPart = workbookPart.WorksheetParts.ElementAt(2);
// The SheetData object will contain all the data.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// Begining Row pointer
int index = 2;
// Database results
var query = from t in db.Clients select t;
// For each item in the database, add a Row to SheetData.
foreach (var item in query)
{
// Cell related variable
string Nom = item.Nom;
// New Row
Row row = new Row();
row.RowIndex = (UInt32)index;
// New Cell
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
// Column A1, 2, 3 ... and so on
cell.CellReference = "A"+index;
// Create Text object
Text t = new Text();
t.Text = Nom;
// Append Text to InlineString object
InlineString inlineString = new InlineString();
inlineString.AppendChild(t);
// Append InlineString to Cell
cell.AppendChild(inlineString);
// Append Cell to Row
row.AppendChild(cell);
// Append Row to SheetData
sheetData.AppendChild(row);
// increase row pointer
index++;
}
// save
worksheetPart.Worksheet.Save();
}
I havent finished yet, my second job is to auto download the spreadsheet after modification.
Finally, i redirect the user to my generated spredsheet (from my aspx)
context.Response.Redirect("Oxml-tpl/generated.xlsx");
just set Response.ContentType = "application/vnd.ms-excel" and your page will rendered as an excel sheet on the clients browser
Sample code here
There are quite a few ways of handling this, depending on how extensive the Excel functionality is. Binoj's answer works if the Excel is just a spreadsheet and has no direct Excel functionality built in. The client can add functionality, concats, etc. These are "dumb" excel docs until the client does soemthing.
To create a more full featured Excel doc, you havve two basic choices that I can think of offhand.
Use either the office components (re: bad) to create an excel document, or a third party component, like SoftArtisan's ExcelWriter. Great component, but there is a cost.
Use a control on the page that allows export to Excel. Most vendors of ASSP.NET controls have this functionality on their grids.
Option #1 allows you pretty much all functionality of Excel. Option #2 is a bit more limited, at least in the controls I have tried.
Good article on how top export to excel from Erika Ehrli
http://blogs.msdn.com/erikaehrli/archive/2009/01/30/how-to-export-data-to-excel-from-an-asp-net-application-avoid-the-file-format-differ-prompt.aspx