I am trying to convert a byte[] I got from an XLS file I have elsewhere, into a new XLSX file and the save it. I'm using Free Spire.XML, but can't figure out how to do it.
public byte[] ConvierteAXLSX(string cuerpo)
{
Workbook wb = new Workbook();
Worksheet sheet = wb.Worksheets[0];
byte[] array = Convert.FromBase64String(cuerpo);
sheet.InsertArray(array, 1, 1, true);
wb.SaveToFile(AppDomain.CurrentDomain.BaseDirectory + "sample.xlsx", ExcelVersion.Version2013);
byte[] fileContent = File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + "sample.xlsx");
//File.Delete(AppDomain.CurrentDomain.BaseDirectory + "sample.xlsx");
return fileContent;
}
This code creates the XLSX file, but just inserts the byte[] into the excel file like an array, instead of converting the data.
Edit:
My problem is slightly different from that other question. I can't just read the original file and then save it again, since the file is in another server and can't access it. The best thing I can do is send the document body and parse it into byte[].
It also works if I can convert my byte[] into a XLS file and save it, then I could use the answer to the other similar question.
Workbook workbook = new Workbook();
workbook.LoadFromFile("Input.xls");
workbook.SaveToFile("Output.xlsx", ExcelVersion.Version2013);
This is not going to war as the two file types store data completely different. The data in the xls file is stored in a proprietary binary format and the xmls file data is stored in Open XML.
I did it, saved the byte[] into a XLS file, read it and saved it again into a XLSX file.
public byte[] ConvierteAXLSX(string cuerpo)
{
File.WriteAllBytes(AppDomain.CurrentDomain.BaseDirectory + "viejo.xls", Convert.FromBase64String(cuerpo));
Workbook workbook = new Workbook();
workbook.LoadFromFile(AppDomain.CurrentDomain.BaseDirectory + "viejo.xls");
workbook.SaveToFile(AppDomain.CurrentDomain.BaseDirectory + "nuevo.xlsx", ExcelVersion.Version2013);
byte[] fileContent = File.ReadAllBytes(AppDomain.CurrentDomain.BaseDirectory + "nuevo.xlsx");
File.Delete(AppDomain.CurrentDomain.BaseDirectory + "viejo.xls");
File.Delete(AppDomain.CurrentDomain.BaseDirectory + "nuevo.xlsx");
return fileContent;
}
Thanks for your help!
Related
My application needs to save a byte[] to disk, the issue is that I know it is an excel file but not what the correct file extension is. Is there a way I can tell if the file is .xls or .xlsx or .xlsm from the data itself?
I ended up writing an extension method to determine the excel file type. This method is not perfect. It will only correctly detect a .xlsm file if the file has a macro.
private static string FindType(this byte[] file)
{
using(MemoryStream ms = new MemoryStream(file))
{
var zf = new ZipArchive(ms, ZipArchiveMode.Read);
if (zf.Entries.Any(e=>e.FullName.StartsWith("xl.")))
{
if (zf.Entries.Any(e=>e.FullName.Equals("xl/vbaProject.bin", StringComparison.InvariantCultureIgnoreCase)))
return ".xlsm";
else
return ".xlsx";
}
}
return string.Empty;
}
I am making an API using C# that takes excel files and transforms and saves its data to database.
I am transforming the excel sheet to base64 and then convert it using epplus to excel sheet.
Problem:
I want to access the sheet without having to save the file.
My Code so far:
public List<ApplicantEngExamBO> receiveAndSaveApplicantData(string database64, int exam_ID)
{
//converting file to byte[]
byte[] byteArray = Convert.FromBase64String(database64);
using (MemoryStream memStream = new MemoryStream(byteArray,0,byteArray.Length))
{
ExcelPackage package = new ExcelPackage(memStream);
package.Load(memStream);
//Just testing if it got any correct data
//It is not working
byte[] data = package.GetAsByteArray("ID");
var res = new List<ApplicantEngExamBO>();
foreach (var d in data)
{
res.Add(new ApplicantEngExamBO { studID = (int)d });
}
//return package;
return res;
}
}
How can we read the contents of the sheet without saving it, what to do next to get the data ? Other columns include "email".
I have a Report Template :
I should be how to export data to Excel files same image.
You should not install Excel on the server which is sometimes seen as a solution. One straightforward way is to create a download as a csv file. This will then open in Excel on the client computer. The following method shows you how to do this:
public ActionResult DownloadSelectedReport(int ReportID)
{
string filename = String.Format("DownloadList{0:yyMMdd}.csv", DateTime.Today);
MemoryStream memStream = new MemoryStream();
UnicodeEncoding uniEncoding = new UnicodeEncoding();
byte[] reportString = uniEncoding.GetBytes(BuildReportAsCSV(ReportID));
memStream.Write(reportString, 0, reportString.Length);
return File(memStream.ToArray(), "application/vnd.ms-excel", Server.UrlEncode(filename));
}
Use BuildReportAsCSV(ReportID) to generate your report for downloading.
I'm using EPPlus to create an excel file on the server. The problem is that I wan't the file to be saved on the clients harddrive and when I the application up on a server I believe this will save the file on the server harddrive.
Is it possible to send this file back to the client/browser some how?
public void CreateAnnuityExcelSheet(List<Calculation> cList, FormCollection form, int DTCyear)
{
List<Calculation> newList = new List<Calculation>();
newList.Add(cList.First()); //Getting the values for the first row
var StartValue = newList[0].StartValue;
var radio = form["advanceOrArrears"];
string fileName = newList[0].CalculationName;
string path = #"C:\ExcelFiles\" + fileName + ".xlsx"; //Path for the file
FileInfo info = new FileInfo(path);
info.Directory.Create(); //If C:\ExcelFiles does not exist, create it
if (!info.Exists)
{
using (ExcelPackage package = new ExcelPackage(info))
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add(fileName);
//Styles for the sheet
package.Save();
}
}
}
The easiest way would be to send the bytes as File to browser. If your library for creating Excel files allows you to save to stream (like for example ClosedXML does) then you can do in your MVC action
var stream = new MemoryStream();
workbook.SaveAs(stream);
stream.Position = 0;
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "file.xlsx");
If you can't save it to memory stream then save it to server's disc and then you can just pass file path and content type to return File().
I've used a httphandler for sending the byte file object to the browser.
This link should help, Generating a file, then launching a secure download
So save the file on the server then transmit it to the user in your controller:
return new FilePathResult(myFilePath,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
I am creating a excel file in the code as Shown Below
Microsoft.Office.Interop.Excel.Application excelFile = CreateExcelFile();
now I want to convert this excelFile to byte[] without saving to hard drive. How is it possible?
had the same problem some time ago. You have to create a temporary file, and then read it to a byte array.
Example code:
string tempPath = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + DateTime.Now.Millisecond + "_temp";//date time added to be sure there are no name conflicts
workbook.SaveAs(tempPath, workbook.FileFormat);//create temporary file from the workbook
tempPath = workbook.FullName;//name of the file with path and extension
workbook.Close();
byte[] result = File.ReadAllBytes(tempPath);//change to byte[]
File.Delete(tempPath);//delete temporary file
That isn't an Excel File it is a COM object used for Excel Automation. It can be used to request Excel to save a document to disk (as a temporary file), which you could then load into a byte[] and then delete the temporary file.
The following code could be used to do this for the active workbook:
public byte[] GetActiveWorkbook(Microsoft.Office.Interop.Excel.Application app)
{
string path = Path.GetTempFileName();
try
{
app.ActiveWorkbook.SaveCopyAs(path);
return File.ReadAllBytes(path);
}
finally
{
if(File.Exists(path))
File.Delete(path);
}
}