Export information to an xlsm file, C# VS asp.net - c#

is there a way to export information to an xlsm file? the steps I do is:
in a button I put an input to select the file, I upload the file to the server
I look for the sheet which is already specified in the code
I modify the file information according to the information to be exported
command to save the file locally.
the error is as follows:
{"The 'br' start tag on line 59 position 30 does not match the end tag of 'font'. Line 60, position 9."}
when indicating the sheet with which to work
I share my code: any suggestions?
public void ExportFile(string FileName, string UserID)
{
FileInfo fi = new FileInfo(FileName);
Master.MSGError = string.Empty;
string SheetName = "test";
using (MemoryStream file = new MemoryStream())
{
try
{
using (ExcelPackage xlPackage = new ExcelPackage(fi))
{
ExcelWorksheet worksheet;
worksheet = xlPackage.Workbook.Worksheets[SheetName]; //here is the error exception
worksheet.Cells[1, 1].Value = "TEST";
//save file
xlPackage.SaveAs(file);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.BinaryWrite(file.ToArray());
Response.Flush();
Response.End();
}
}
catch (Exception ex)
{
Master.fc.MSGError = ex.Message;
}
}
}

Currently I solved my problem I thought that the detail was in the macro, but I found the real error doing different tests, it seems that both epplus and closedxml have problems reading certain information in the excel, I ended up using closedxml and applying the solution:
OpenXml Excel: throw error in any word after mail address
I'm sorry for confusion

Related

Converting a .xlsx file to .csv using Syncfusion.XlsIO - Null reference exception

I have a file in blob storage that is in .xslx format and I am trying to convert it to .csv format using Syncfusion.XlsIO Nuget package.
I have tried the following:
private async Task ConvertExcelToCsv()
{
var fileName = await _fileStore.GetContainerFileAsync(AppSettingsConstants.FileNames.Container, "myfile.xlsx");
using (ExcelEngine excelEngine = new ExcelEngine())
{
var application = excelEngine.Excel;
var workbook = application.Workbooks.Open(fileName.Name);
var worksheet = workbook.Worksheets[1];
worksheet.SaveAs("myfile.csv", ",");
}
}
When I debug, the fileName is retrieved successfully, but the application breaks on using (ExcelEngine excelEngine = new ExcelEngine()) with a NullReferenceException error.
Where am I going wrong here?
The way you can do it is defined here: https://www.syncfusion.com/kb/9098/how-to-export-excel-data-to-csv-file
Most likely, you would need to install from NuGet not only Syncfusion.XlsIO.WinForms , but also System.Drawing.Common and System.Security.Permissions.
This code worked:
try
{
//Initialize ExcelEngine
using (ExcelEngine excelEngine = new ExcelEngine())
{
//Initialize Application
IApplication application = excelEngine.Excel;
//Set default version for application
application.DefaultVersion = ExcelVersion.Excel2013;
//Open a workbook to be export as CSV
IWorkbook workbook = application.Workbooks.Open(#"E:\Users\Public\Documents\" + "ExcelFile.xlsx");
//Accessing first worksheet in the workbook
IWorksheet worksheet = workbook.Worksheets[0];
//Save the workbook to csv format
worksheet.SaveAs("Output.csv", ",");
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
Make sure you have permission to access the Excel file. Usually, it helps if you test it with files which are saved on another drive than on which Windows is installed (e.g. E:\, if Windows is on C:\).
Thank you, it turned out I was missing a reference to System.Drawing nuget

File wont open after saving

I have some code that is suppose to enter some values into several excel workbooks. Right now the program doesn't even put any values into the workbooks and only saves them. Even like this i get this error when opening the files: Excel cannot open the file **.xlsm because the file format or file extension is not valid. Verify that the file has been corrupted and that the file extension matches the format of the file.
I have writen many programs that work with excel files and never had this problem. In the code you can see that i basically just go through a for loop and save the file.
try
{
fileInfo = new FileInfo(Path.GetDirectoryName(Application.StartupPath) + '\\' + partners[partner].partnerName + #"\PDP_ExSumm_" + partners[partner].partnerName + ".xlsm");
using (ExcelPackage excelPackage = new ExcelPackage(fileInfo))
{
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
for (int cell = 0; cell < ExSummCells.Count; cell++)
{
if (ExSummCells[cell] != "")
{
// worksheet.Cells[ExSummCells[cell]].Value = partners[partner].exSummData[partner];
}
excelPackage.Save();
}
}

Excel export (xlsx) error Exception of type 'System.OutOfMemoryException' was thrown

I am facing System.OutOfMemoryException while exporting .xlsx file from ASP .Net this is happening while writing the data into memory stream.
protected void ExportExcel(string strWorkbookName, DataTable dt)
{
try
{
dt.TableName = strWorkbookName;
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt);
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + strWorkbookName + ".xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
//HttpContext.Current.Response.SuppressContent = true; // Gets or sets a value indicating whether to send HTTP content to the client.
//HttpContext.Current.ApplicationInstance.CompleteRequest();
Response.End();
}
}
}
catch (Exception ex)
{
string errorMessage = string.Empty;
throw ex;
}
}
Exception is being occurred on line wb.SaveAs(MyMemoryStream);
XLWorkbook class belong to ClosedXML.dll, v0.69.1.0 library for exporting excel.
Reference: https://closedxml.codeplex.com/
anyone any idea!?!
How to resolve this?
A few years ago, I wrote an "Export to Excel" C# class, and faced the same issue with large data sets.
The solution was to use the OpenXmlWriter library, so your code isn't attempting to put together the entire Excel file in memory, before writing it our to a file.
In your example, simply take your DataTable, dt, and pass it to my library, and the problem goes away. You'll have a real .xlsx file, created using Microsoft's OpenXML library.
try
{
dt.TableName = strWorkbookName;
CreateExcelFile.CreateExcelDocument(dt, "YourExcelFilename.xlsx");
}
catch (Exception ex)
{
// Handle any execptions..
}
Or, as you're including this in an ASP.Net application, you can get my library to save the Excel file directly to your page's Response:
CreateExcelFile.CreateExcelDocument(dt, "YourExcelFilename.xlsx", Response);
My source code is available to download (for free) here:
Export to Excel

Saving HTML from MemoryStream into a Excel file

I have a XSLT transformed HTML data in MemoryStream (in C#). I am trying to convert this to an Excel format before emailing, preferably conversion happens all in memory again without saving to local disk. I can worry about the email attachment part later. Can anyone point me to a sample on how I could do the conversion from HTML to Excel format either through OpenXML or with Office.Interop.Excel.
The HTML data is well formed and I could manually do the conversion by opening the html in Excel application and do a Save As to save it in xlsx format (Office 2010), no problem. I also tried to simply change the .html extension to .xlsx, but then excel complains about opening it.
What's the best way to automate the manual SaveAs action so that I could use the same html data in Excel format? I understand that I could create a separate .xslt for directly converting my XML into Excel format. But, that'll be too many .xslt to maintain. I'm trying to find the hack to let Excel do the work for me.
Thank you for any and all pointers in advance!
EDIT:
I figured I have no choice but to store html to disk and read it back and use Excel Interop to do SaveAs method. When I did try though, getting the exception with HRESULT: 0x800A03EC on the SaveAs method. Here's how to reproduce it.
steps to reproduce the behavior
Save this text
<html><head></head><body><center><h1>Test Header</h1></center></body></html>
as C:\Test.html
after making reference to Excel interop like this,
using Excel = Microsoft.Office.Interop.Excel;
Try this code
`
var app = new Excel.Application();
Excel.Workbook wb = null;
try
{
wb = app.Workbooks.Open(#"c:\test.html");
wb.SaveAs(#"c:\test.xlsx", Excel.XlFileFormat.xlOpenDocumentSpreadsheet);
//wb.SaveCopyAs(#"c:\test.xlsx");
wb.Close();
}
catch (Exception ex)
{
//_logger.Error(ex);
}
finally
{
app.Quit();
}
`
I always get the mentioned exception on SaveAs no matter which fileformat I choose or even not mentioning the fileformat there..
Any ideas?
This code works. It turns out the exception I was getting is only related to the file format I was trying to save. When I changed it to Open XML workbook, it saved fine.
using Excel = Microsoft.Office.Interop.Excel;
.
.
.
var app = new Excel.Application();
Excel.Workbook wb = null;
try
{
wb = app.Workbooks.Open(#"c:\test.html");
wb.SaveAs(#"c:\test.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook);
//wb.SaveCopyAs(#"c:\test.xlsx");
wb.Close();
}
catch (Exception ex)
{
//_logger.Error(ex);
}
finally
{
app.Quit();
}
Here's the updated code that takes bytes[] html as input and returns xlsx in bytes[]
public static byte[] DoConvertXlDataToOpenXml(byte[] data, FileInfo fileInfo)
{
ExcelInterop.Application excelApp = null;
ExcelInterop.Workbooks workBooks = null;
ExcelInterop.Workbook workBook = null;
FileInfo tempFile = null;
FileInfo convertedTempFile = null;
try
{
//Stream the file to temporary location, overwrite if exists
tempFile = new FileInfo(Path.ChangeExtension(Path.Combine(Path.GetTempFileName()), fileInfo.Extension));
using (var destStream = new FileStream(tempFile.FullName, FileMode.Create, FileAccess.Write))
{
destStream.Write(data, 0, data.Length);
}
//open original
excelApp = new ExcelInterop.Application();
excelApp.Visible = false;
excelApp.DisplayAlerts = false;
workBooks = excelApp.Workbooks;
workBook = workBooks.Open(tempFile.FullName);
convertedTempFile = new FileInfo(Path.ChangeExtension(Path.GetTempFileName(), "XLSX"));
//Save as XLSX
excelApp.Application.ActiveWorkbook.SaveAs(
convertedTempFile.FullName
, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook
, ConflictResolution: ExcelInterop.XlSaveConflictResolution.xlLocalSessionChanges);
excelApp.Application.ActiveWorkbook.Close();
return File.ReadAllBytes(convertedTempFile.FullName);
}
catch (Exception)
{
throw;
}
finally
{
if (workBooks != null)
Marshal.ReleaseComObject(workBooks);
if (workBook != null)
Marshal.ReleaseComObject(workBook);
if (excelApp != null)
Marshal.ReleaseComObject(excelApp);
if (tempFile != null && tempFile.Exists)
tempFile.Delete();
if (convertedTempFile != null && convertedTempFile.Exists)
{
convertedTempFile.Delete();
}
}
}

Convert XLSM to XLSX

I'm using the EPPLUS library to read data from Excel to create another file. Unfortunately it does not support the .XLSM extension file. Is there a nice way to convert .XLSM files to .XLSX file for the purpose of reading the file with EPPLUS?
(using EPPLUS for reading would be nice because all my code is already written using it :) )
In order to do this you will need to use the Open XML SDK 2.0. Below is a snippet of code that worked for me when I tried it:
byte[] byteArray = File.ReadAllBytes("C:\\temp\\test.xlsm");
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
using (SpreadsheetDocument spreadsheetDoc = SpreadsheetDocument.Open(stream, true))
{
// Change from template type to workbook type
spreadsheetDoc.ChangeDocumentType(SpreadsheetDocumentType.Workbook);
}
File.WriteAllBytes("C:\\temp\\test.xlsx", stream.ToArray());
}
What this code does is it takes your macro enabled workbook file and opens it into a SpreadsheetDocument object. The type of this object is MacroEnabledWorkbook, but since you want it as a Workbook you call the ChangeDocumentType method to change it from a MacroEnabledWorkbook to a Workbook. This will work since the underlying XML is the same between a .xlsm and a .xlsx file.
Using the Open XML SDK, like in amurra's answer, but
in addition to changing doc type, VbaDataPart and VbaProjectPart should be removed, otherwise Excel will show error a file is corrupted.
using (var inputStream = File.OpenRead("C:\\temp\\test.xlsm"))
using (var outStream = new MemoryStream()) {
inputStream.CopyTo(outStream);
using (var doc = SpreadsheetDocument.Open(outStream, true)) {
doc.DeletePartsRecursivelyOfType<VbaDataPart>();
doc.DeletePartsRecursivelyOfType<VbaProjectPart>();
doc.ChangeDocumentType(DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
}
File.WriteAllBytes("C:\\temp\\test.xlsx", outStream.ToArray());
}
package xlsbtoxlsx;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbookType;
public class XlsbToXlsxConvertor {
public static void main(String[] args) throws Exception {
String inputpath="C:\\Excel Data Files\\XLSB\\CSD_TDR_20200823";
String outputpath="C:\\Excel Data Files\\XLSB\\output";
new XlsbToXlsxConvertor().xlsmToxlsxFileConvertor(inputpath, outputpath);
}
public void xlsmToxlsxFileConvertor(String inputpath, String outputpath) throws Exception {
XSSFWorkbook workbook;
FileOutputStream out;
System.out.println("inputpath " + inputpath);
File directoryPath = new File(inputpath);
// List of all files and directories
String contents[] = directoryPath.list();
System.out.println("List of files and directories in the specified directory:");
for (int i = 0; i < contents.length; i++) {
System.out.println(contents[i]);
// create workbook from XLSM template
workbook = (XSSFWorkbook) WorkbookFactory
.create(new FileInputStream(inputpath + File.separator + contents[i]));
// save copy as XLSX ----------------START
OPCPackage opcpackage = workbook.getPackage();
// get and remove the vbaProject.bin part from the package
PackagePart vbapart = opcpackage.getPartsByName(Pattern.compile("/xl/vbaProject.bin")).get(0);
opcpackage.removePart(vbapart);
// get and remove the relationship to the removed vbaProject.bin part from the
// package
PackagePart wbpart = workbook.getPackagePart();
PackageRelationshipCollection wbrelcollection = wbpart
.getRelationshipsByType("http://schemas.microsoft.com/office/2006/relationships/vbaProject");
for (PackageRelationship relship : wbrelcollection) {
wbpart.removeRelationship(relship.getId());
}
// set content type to XLSX
workbook.setWorkbookType(XSSFWorkbookType.XLSX);
// write out the XLSX
out = new FileOutputStream(outputpath + File.separator + contents[i].replace(".xlsm", "") + ".xlsx");
workbook.write(out);
out.close();
System.out.println("done");
workbook.close();
}
}
}

Categories

Resources