I am exporting a data table to Excel using EPPlus but I keep getting no results. I get a worksheet with headers and a label on the tab but no data. I verified that the tableadapter has data in it.
Here is my code:
FileInfo newFile = new FileInfo("c:\temp\fn.xlsx");
ExcelPackage epp = new ExcelPackage(newFile);
var ws = epp.Workbook.Worksheets.Add(acctno);
TransTableAdapter.FillByAcct(MSDataSet.TransWithName, acctno);
ws.Cells.LoadFromDataTable(MSDataSet.TransWithName, true, OfficeOpenXml.Table.TableStyles.Light8);
epp.Save();
epp.Dispose();
Please kindly help if you can. Thanks!
In case anyone else runs into this problem, here is the solution -- use GET and not FILL:
MSDataSet.TransDataTable newTransTable;
newTransTable = TransTableAdapter.GetDataByDFI(#acctno);
ws.Cells.LoadFromDataTable(newTransTable, true, OfficeOpenXml.Table.TableStyles.Light8);
Related
I got Excel xlsx document with hyperlinks.
Hyperlinks have adresses and subaddresses (that's the way VBA call Html fragments, all after # sign)
Epplus library has Hyperlink property for every cell, but it has only first part of html address, so instead of
stackoverflow.com#footer
I got:
stackoverflow.com
Is there any way to read the html fragment part with this library ?
Code for reading hyperlinks via epplus:
FileInfo xlsxFile = new FileInfo(_filePath);
using (ExcelPackage pck = new ExcelPackage(xlsxFile))
{
var wb = pck.Workbook;
if (wb == null)
return null;
var ws = wb.Worksheets.FirstOrDefault();
ExcelRange er = ws.Cells[0,0];
var hyperlink = er.Hyperlink;
It seems to be an issue with the way excel store hyperlinks and the way Epplus reads them. Excel stores the hyperlinks both in the worksheet itself as well as the relationship file for the worksheet which is a file that stores any kind of cross referencing between workbook parts (worksheets, styles, strings, etc). This all has to do with the structure of the an xlsx file which is xml based off of the OpenOffice XML standard: OpenOffice XML Info
So the problem is Epplus is relying on that relationship file which does not contain the fragment while the `hyperlink' node in the worksheet xml does. You can see all of this in its gory detail if you open up the xlsx file as a zip file by renaming it.
So, the short answer is you are forced to use the `.Value' of the cell object. Not as clean but it will work. For example, if I create a cell like this:
with this code:
var fi = new FileInfo(#"c:\temp\Html_Fragment.xlsx");
using (var pck = new ExcelPackage(fi))
{
var wb = pck.Workbook;
var ws = wb.Worksheets.FirstOrDefault();
ExcelRange er = ws.Cells[1,1];
var hyperlink = er.Hyperlink;
Console.WriteLine(er.Value);
Console.WriteLine("{{Value: {0}, Hyperlink: {1}}}", er.Value, er.Hyperlink.AbsoluteUri);
}
Gives this:
{
Value: https://msdn.microsoft.com/en-us/library/aa982683(v=office.12).aspx#Anchor_3,
Hyperlink: https://msdn.microsoft.com/en-us/library/aa982683(v=office.12).aspx
}
I trimmed out quite a bit so if there is context missing sorry, I'll edit.
I'm not getting any errors and the Picture does seems to get added to the workbook object...
I've also tried just inserting into a new cell(), but when I get to saving to the stream it get an Invalid Cell value.
I'm using this link as a reference: https://excellibrary.googlecode.com/svn-history/r51/trunk/src/ExcelLibrary.WinForm/Form1.cs
Workbook wBook = new Workbook();
Worksheet wSheet = new Worksheet();
//getting my file
var path = context.Server.MapPath("~/data/default/content/logo.bmp");
pic.Image = ExcelLibrary.SpreadSheet.Image.FromFile(path);
pic.TopLeftCorner = new CellAnchor(5, 1, 0, 0);
pic.BottomRightCorner = new CellAnchor(7, 5, 592, 243);
wSheet.AddPicture(pic);
wSheet.Cells[rows, 0] = new Cell("some text");
wBook.Worksheets.Add(wSheet);
context.Response.AddHeader("Content-Disposition","Attachment;Filename=PlattShoppingCart.xls");
context.Response.ContentType = "application/vnd.ms-excel";
MemoryStream stream = new MemoryStream();
wBook.SaveToStream(stream);
context.Response.BinaryWrite(stream.ToArray());
This question and answer uses Microsoft.Interop Excel, but it accomplishes the same task. Probably not the answer you need, but I got it to work just fine. Of course, I was already using the interop stuff, just needed to modify the code a little to get it work.
I wonder if you forgot to add the ExcelLibrary equivalent of
pic.Placement = // Can be any of Excel.XlPlacement.XYZ value
I don't know if it was just me or it's actually not anywhere in the documentation, but *.bmp, *.jpeg, *.gif', are not supported and it worked by simply turning it into a .png....
Thanks for the link though as it was an experience to compare it to other methods.
Here are some other links if you find yourself getting this far and you still have issues:
http://www.codeproject.com/Questions/793324/How-Do-I-Insert-Jpg-Image-From-File-Stream
http://www.codeproject.com/Questions/84487/How-to-insert-a-picture-image-in-XML-spreadsheet
How Do I Create a System.Windows.Media.ImageSource From a Byte Array?
I have a C# data processing application which uses EPPlus to write the final results into an excel sheet. The background color of the rows are changed based on what the data on that row signifies. Time was never an issue as I only dealt with files that were below <100MB before. However, as my requirements have changed and the files get larger, I have noticed that.. just coloring makes my application 60% slower. Removing coloring makes the application significantly faster. The snippet below is an example of the code which I use to color the data to make it visually distinguishing. I'm no expert at EPPlus but is there a way, this can be optimized to make my application faster? Or are there any better ways for me to make the rows visually distinct for the people who will end up looking at the data? Any help will be appreciated!
if (data[4] == "3")
{
// color the type 3 messages here
var fill1 = cell1.Style.Fill;
fill1.PatternType = ExcelFillStyle.Solid;
fill1.BackgroundColor.SetColor(Color.LightGray);
}
if (data[4] == "4")
{
var fill1 = cell1.Style.Fill;
fill1.PatternType = ExcelFillStyle.Solid;
fill1.BackgroundColor.SetColor(Color.BlanchedAlmond);
}
EDIT:
This is the code I use to copy the template and write the excel data into the new worksheet. p is an Excel Package which I convert to a byte Array before writing to the excel file.
Byte[] bin = p.GetAsByteArray();
File.Copy("C:\\Users\\mpas\\Desktop\\template.xlsx", "C:\\Users\\mpas\\Desktop\\result.xlsx");
using (FileStream fs = File.OpenWrite("C:\\Users\\mpas\\Desktop\\result.xlsx")) {
fs.Write(bin, 0, bin.Length);
}
Styling is much faster in EPPlus, and most Excel APIs, if you use named styles. Assign and use the style to cell in EPPlus like this ...
internal static string YourStyleName = "MyStyle";
ExcelNamedStyleXml yourStyle = excel.Workbook.Styles.CreateNamedStyle(YourStyleName);
yourStyle.Style.Font.Color.SetColor(Color.DarkRed);
yourStyle.Style.Fill.PatternType = ExcelFillStyle.Solid;
yourStyle.Style.Fill.BackgroundColor.SetColor(Color.LemonChiffon);
// ...
sheet.Cells[sourceRange].StyleName = YourStyleStyleName
Here is code to open an existing file.
FileInfo AddressList = new FileInfo("c:\test\test.xlsx");
// Open and read the XlSX file.
try
{
using (ExcelPackage package = new ExcelPackage(AddressList))
{
// Get the work book in the file
ExcelWorkbook workBook = package.Workbook;
if (workBook != null)
{
if (workBook.Worksheets.Count > 0)
{
// Get the first worksheet
//ExcelWorksheet Worksheet = workBook.Worksheets.First();
var worksheet = package.Workbook.Worksheets[1];
I am using the below code
// Declare variables and get the export options.
ExportOptions exportOpts = new ExportOptions();
ExcelFormatOptions excelFormatOpts = new ExcelFormatOptions();
DiskFileDestinationOptions diskOpts = new DiskFileDestinationOptions();
exportOpts = rpt.ExportOptions;
// Set the excel format options.
excelFormatOpts.ExcelConstantColumnWidth = 100;
excelFormatOpts.ExcelUseConstantColumnWidth = true;
exportOpts.ExportFormatType = ExportFormatType.ExcelRecord;
exportOpts.FormatOptions = excelFormatOpts;
// Set the disk file options and export.
exportOpts.ExportDestinationType = ExportDestinationType.DiskFile;
diskOpts.DiskFileName = strFilename;
exportOpts.DestinationOptions = diskOpts;
rpt.Export();
I am getting the data's exported to excel correctly without formating.
Question: Now I need to format. I want to set column width in the excel.
Can I do it?
From my above code the below lines seems not to function
excelFormatOpts.ExcelConstantColumnWidth = 100;
excelFormatOpts.ExcelUseConstantColumnWidth = true;
I appreciate any help in this regard as this issue is eating my time.
i am assuning that you have excel worksheet object with a name esheet.
esheet.Cells.Style.EntireColumn.AutoFit();
try this.
I see two problems in your code.
With ExportFormatType.ExcelRecord you should use ExcelDataOnlyFormatOptions class, not ExcelFormatOptions. ExcelFormatOptions corresponds to ExportFormatType.Excel
ExcelConstantColumnWidth in C# version is in twips and 100 is very small value. You should multiply it by 20.
I managed to get working code for ExportFormatType.Excel case, but not for ExportFormatType.ExcelRecord. Other properties of ExcelDataOnlyFormatOptions work, but ExcelConstantColumnWidth still doesn't work for me.
I have a datatable with larger than 300.000 row, i want export this datatable to excel 2003 but don't use Excel COM. I have used NPOI but it raise error OutOfMemory. I'm finding a thirt party component (free) can export for each row and write directly to file to avoid out of memory. Who can help me? thanks.
How about a csv file ? It is readable from Excel.
Try this Libs. I am not sure about the capacity
http://ehl.codeplex.com/
http://excelexportlib.codeplex.com/
You can export to an excel-file with the use of a webgrid (only in code). Under the assumption that you're creating a WinForm-application, you will have to make a reference to the System.Web library.
// Create the DataGrid and perform the databinding
var myDataGrid = new System.Web.UI.WebControls.DataGrid();
myDataGrid.HeaderStyle.Font.Bold = true;
myDataGrid.DataSource = myDataTable;
myDataGrid.DataBind();
string myFile = "put the name here with full path.xls"
var myFileStream = new FileStream( myFile, FileMode.Create, FileAccess.ReadWrite );
// Render the DataGrid control to a file
using ( var myStreamWriter = new StreamWriter( myFileStream ) )
{
using (var myHtmlTextWriter = new System.Web.UI.HtmlTextWriter(myStreamWriter ))
{
myDataGrid .RenderControl( myHtmlTextWriter );
}
}
I haven't tested it with so many records, so I don't know the impact of this memory-wise.
Edit:
Take note of the comment of #Charles Williams that excel 2003 has a row limitation