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.
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 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!
I'm calling the action "Export" where i pass a list of viewmodels and define the format
public ActionResult DownloadTokenlist(string startDate = null, string endDate = null)
{
using (HRCTSStatisticDb db = new HRCTSStatisticDb(Setting.ClientId))
{
List<TokenExportViewModel> tokenExportViewModels = new List<TokenExportViewModel>();
Response.AddHeader("content-disposition", $"attachment;filename=Tokenlist_{DateTime.Now.ToString("dd.MM.yyyy")}.xlsx");
log.InfoFormat($"The {new HomeController().UserRole(Context.LoggedInUser)}: {Context.LoggedInUser} has used the exceldownload");
return File(new ExcelExport().Export(tokenExportViewModels), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
The action i call (ExcelEngine is by Syncfusion):
public MemoryStream Export(List<TokenExportViewModel> list)
{
MemoryStream stream = new MemoryStream();
using (ExcelEngine excelEngine = new ExcelEngine())
{
IApplication application = excelEngine.Excel;
application.DefaultVersion = ExcelVersion.Excel2010;
IWorkbook workbook = application.Workbooks.Create(1);
IWorksheet worksheet = workbook.Worksheets.Create("Tokenlist");
IStyle defaultStyle = workbook.Styles.Add("default");
defaultStyle.Font.Size = 12;
worksheet.SetDefaultColumnStyle(1, 20, defaultStyle);
worksheet.SetDefaultRowStyle(1, 300, defaultStyle);
worksheet.UsedRange.AutofitColumns();
worksheet.Range["A1"].Text = $"Tokenlist - {DateTime.Today.ToString("dd.MM.yyyy")}";
worksheet.Range["A1"].CellStyle = h1Style;
workbook.SaveAs(stream);
workbook.Close();
}
return stream;
}
I only posted the code which has an impact on the file and (maybe) could create the error.
There is no error, until i open the file, then this exception pops up:
Excel cannot open the file 'Tokenlist_22.05.2018.xlsx' because the
file format or file extension is not valid. Verify that the file has
not been corrupted and that the file extension matches the format of
the file.
I've tried to change the file format to .xls and .vbs but neither works. With .xls I can open the document but then it has no data in it.
The .close() doesn't change much, it just closes the output stream previously opened.
As stream reached end position while returning it, the downloaded file is getting corrupted. So, it is recommended to set its current position to 0 to resolve this issue. Please refer below code to achieve the same.
Code Example:
workbook.SaveAs(stream);
workbook.Close();
stream.Position = 0;
We have also shared a simple sample for your reference which can be downloaded from following link.
Sample Link: http://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample1020485770.zip
I work for Syncfusion.
Use the FileContentResult Overload where you can provide thefileDownloadName like this:
return File(excelExport.Export(tokenExportViewModels).ToArray(),"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"Tokenlist_{DateTime.Now.ToString("dd.MM.yyyy")}.xlsx");
And use the stream ToArray() extension to return a byte[].
(I assume your Export method is generating a valid document)
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")