So I have an issue I want display a View to indicate to the end user that their request to download/open an Excel spreadsheet is processing, and then I want to have the Excel spreadsheet open, and the View close.
Currently, I get a blank Screen and then the Excel opens
so 3 things:
Display View with a Preloader
Open/Download an Excel Spreadsheet
Close the View, after spreadsheet opens
Here is the View:
#{
ViewBag.Title = "CoursePriceHistory";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Course Price History</h2>
<img src="~/Images/loading.gif" />
Here is the ActionResult from the Controller:
public ActionResult CoursePriceHistory()
{
// Sql Statement to provide parameters for Quarter Year (MIN/MAX)
DAL.QuarterYear qy = new DAL.QuarterYear();
var min = qy.getMIN();
var max = qy.getMAX();
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Render arguments
byte[] result = null;
string fileName = #"\\department.chicagobooth.edu\Test\something.pdf";
string reportPath = #"/Sam - Faculty and Course Reports/Course Price History";
string format = "EXCEL";
string historyID = null;
string encoding;
string mimeType;
string extension;
ReportService.Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
ParameterValue[] parameters = new ParameterValue[3];
parameters[0] = new ParameterValue();
parameters[0].Name = "StartQuarterYear";
parameters[0].Value = min;
parameters[1] = new ParameterValue();
parameters[1].Name = "EndQuarterYear";
parameters[1].Value = max;
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
rs.SetExecutionParameters(parameters, "en-us");
result = rs.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
MemoryStream ms = new MemoryStream(result);
// Write PDF
Response.Clear();
Response.AddHeader("Content-Disposition", "inline; filename=Course Price History");
Response.AddHeader("Content-Type", "application/Excel");
Response.ContentType = "application/vnd.ms-excel";
Response.OutputStream.Write(ms.ToArray(), 0, ms.ToArray().Length);
Response.Buffer = true;
Response.Flush();
Response.Close();
return View();
}
Related
I am trying to download an xlsx file from an ftp but when I download and try to open it I get that it is a corrupt file. . I share the back and front code.
public async Task<TransacResult> DownloadFileInterface(Uri serverUri, string fileName)
{
StreamReader sr;
byte[] fileContent;
try
{
string ftpUser = GetConfiguration()["SuatKeys:FTPSuatUser"];
string ftpPassword = GetConfiguration()["SuatKeys:FTPSuatPassword"];
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = false;
request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
sr = new StreamReader(request.GetResponse().GetResponseStream());
fileContent = Encoding.UTF8.GetBytes(sr.ReadToEnd());
sr.Close();
sr.Dispose();
FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync();
var fileContentResult = new FileContentResult(fileContent, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = fileName + ".xlsx"
};
return new TransacResult(true, fileContentResult);
}
catch (Exception ex)
{
return new TransacResult(false, new Message("SUAT-ERR-C02", MessageCategory.Error, "Conexión rechazada", ex.Message));
}
}
async downloadlayout() {
var obj = this.interfaces.item;
if (this.$store.state.usuarioActivo.modeD == 0)
obj = serialize(obj);
const res = await this.$store.dispatch("apiPost", {
url: "Interface/DownloadDinamycLayout",
item: obj
})
console.clear();
console.log(res);
const a = document.createElement("a");
a.href = "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64," + res.fileContents;
a.download = res.fileDownloadName;
a.click();
a.remove();
},
reading the file does not present any problem
Greetings
Assuming you the file on FTP isn't corrupted, the problem have is that .xlsx files are not textual files, but StreamReader is intended for reading text. Using it as you are will corrupt arbitrary binary data (e.g. an .xlsx file).
I would personally just stream the file from FTP, through your server, and straight to the client:
public async Task<TransacResult> DownloadFileInterface(Uri serverUri, string fileName)
{
StreamReader sr;
byte[] fileContent;
try
{
string ftpUser = GetConfiguration()["SuatKeys:FTPSuatUser"];
string ftpPassword = GetConfiguration()["SuatKeys:FTPSuatPassword"];
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = false;
request.Credentials = new NetworkCredential(ftpUser, ftpPassword);
Stream ftpFileStream = request.GetResponse().GetResponseStream();
var fileContentResult = new FileStreamResult(ftpFileStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = fileName + ".xlsx"
};
return new TransacResult(true, fileContentResult);
}
catch (Exception ex)
{
return new TransacResult(false, new Message("SUAT-ERR-C02", MessageCategory.Error, "Conexión rechazada", ex.Message));
}
}
I tried three times with two Actions:
[HttpPost]
public FileResult download(IFormFile file)
{
var filestream = file.OpenReadStream();
var filestreamreader = new StreamReader(filestream, Encoding.Default);
var fileContent1 = Encoding.Default.GetBytes(filestreamreader.ReadToEnd());
return File(fileContent1, "application/ms-excel", "3.xlsx");
}
[HttpPost]
public FileResult download1(IFormFile file)
{
var filestream = file.OpenReadStream();
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
ExcelPackage package = new ExcelPackage(filestream);
var fileContent = package.GetAsByteArray();
return File(fileContent, "application/ms-excel", "3.xlsx");
}
At First,I tried to read the content of txt file and xlsx file ,you could see we could get the content string of txt file,but failed to get the string in xlsx file
Then I tried to get the content byte from stream again with EPPlus and succeeded
The ResulT:
The reason I recomanded EEplus: If Oneday we want to download the xlsx file with some extra infomation,we could just add some codes rather than delet the codes and write again
codes as below;
[HttpPost]
public FileResult download1(IFormFile file)
{
var employeelist = new List<Employee>()
{
new Employee(){Id=1,Name="Jhon",Gender="M",Salary=5000},
new Employee(){Id=2,Name="Graham",Gender="M",Salary=10000},
new Employee(){Id=3,Name="Jenny",Gender="F",Salary=5000}
};
var stream = file.OpenReadStream();
byte[] fileContent;
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(stream))
{
// add a new worksheet to the empty workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Employee");
//Set the Width and Height
//worksheet.Column(1).Width = xx;
//worksheet.Row(1).Height = xx;
//Add the headers
worksheet.Cells[1, 1].Value = "ID";
worksheet.Cells[1, 2].Value = "Name";
worksheet.Cells[1, 3].Value = "Gender";
worksheet.Cells[1, 4].Value = "Salary (in $)";
for(int i=0; i< employeelist.Count; i++)
{
worksheet.Cells[i + 2, 1].Value = employeelist[i].Id;
worksheet.Cells[i + 2, 2].Value = employeelist[i].Name;
worksheet.Cells[i + 2, 3].Value = employeelist[i].Gender;
worksheet.Cells[i + 2, 4].Value = employeelist[i].Salary;
}
package.Save(); //Save the workbook.
fileContent = package.GetAsByteArray();
}
return File(fileContent, "application/ms-excel", "target.xlsx");
}
The Result:
I am trying to pass a PDF generated from a SQL ReportServer back to a UWP application as a PdfDocument. I keep getting an Exception when trying to create the StorageFile
[HttpGet]
[Route("invoicereport/{report}/{invoice}")]
public async Task<IHttpActionResult> GetInvoiceReport([FromUri] string report, [FromUri] string invoice)
{
try
{
Debug.WriteLine("Test");
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = CredentialCache.DefaultCredentials;
rs.Url = "http://localhost/reportserver/reportexecution2005.asmx";
rs.ExecutionHeaderValue = new ExecutionHeader();
var executionInfo = new ExecutionInfo();
executionInfo = rs.LoadReport($"{ReportsDir}/Invoice/{report}", null);
List<ParameterValue> parameters = new List<ParameterValue>();
parameters.Add(new ParameterValue { Name = "SOPNUMBER", Value = invoice });
parameters.Add(new ParameterValue { Name = "SOPTypeString", Value = "Invoice" });
rs.SetExecutionParameters(parameters.ToArray(), "en-US");
string deviceInfo = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
string mimeType;
string encoding;
string[] streamId;
Warning[] warning;
var result = rs.Render("PDF", deviceInfo, out mimeType, out encoding, out encoding, out warning, out streamId);
FileStream stream = File.Create(System.Web.HttpRuntime.CodegenDir + $"/{invoice}.pdf", result.Length);
//write file with rendered result
stream.Write(result, 0, result.Length);
//close stream
stream.Close();
StorageFile file = StorageFile.GetFileFromPathAsync(System.Web.HttpRuntime.CodegenDir + $"/{invoice}.pdf").GetResults();
var pdf = PdfDocument.LoadFromFileAsync(file).GetResults();
return Ok(pdf);
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Reporting Error");
}
return Ok();
}
the Exception gets logged as:
System.IO.FileNotFoundException: The system cannot find the file specified. (Exception from HRESULT: 0x80070002)
at Windows.Foundation.IAsyncOperation`1.GetResults()
at Prism.Web.Queries.Controllers.ReportController.<GetInvoiceReport>d__6.MoveNext() in C:\Projects\PointOfSaleBeta\Prism.Web.Queries\Controllers\ReportController.cs:line 183
Line 183 corresponds to StorageFile file = StorageFile.GetFileFromPathAsync(System.Web.HttpRuntime.CodegenDir + $"/{invoice}.pdf").GetResults();
I have verified (many times) that the referenced PDF file actually got created. Am I not using the correct syntax for 'GetFileFromPathAsync`?
After I didn't get any answers or comments I tried a different approach. I installed the FreeSpire.PDF nuget package:
[HttpGet]
[Route("invoicereport/{report}/{invoice}")]
public async Task<IHttpActionResult> GetInvoiceReport([FromUri] string report, [FromUri] string invoice)
{
try
{
Debug.WriteLine("Test");
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = CredentialCache.DefaultCredentials;
rs.Url = "http://localhost/reportserver/reportexecution2005.asmx";
rs.ExecutionHeaderValue = new ExecutionHeader();
var executionInfo = new ExecutionInfo();
executionInfo = rs.LoadReport($"{ReportsDir}/Invoice/{report}", null);
List<ParameterValue> parameters = new List<ParameterValue>();
parameters.Add(new ParameterValue { Name = "SOPNUMBER", Value = invoice });
parameters.Add(new ParameterValue { Name = "SOPTypeString", Value = "Invoice" });
rs.SetExecutionParameters(parameters.ToArray(), "en-US");
string deviceInfo = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
string mimeType;
string encoding;
string[] streamId;
Warning[] warning;
var result = rs.Render("PDF", deviceInfo, out mimeType, out encoding, out encoding, out warning, out streamId);
PdfDocument pdf = new PdfDocument();
pdf.LoadFromBytes(result);
return Ok(pdf);
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Reporting Error");
}
return Ok();
}
This solved (worked around) my problem.
I want to export a list to CSV file using MVC, Jquery. I want to write to a file to the response stream but doesn't do anything. No Download appear.
Below is my code in .cshtml
<button id="btnGenerateCSV">Generate CSV</button>
in .js
$('#btnGenerateCSV').click(function () {
$.post(root + "ClaimInternal/DownloadCsv");
});
In myController
private string GetCsvString(IList<Area> Area)
{
StringBuilder csv = new StringBuilder();
csv.AppendLine("AreaID,AliasName,Description,BankName");
foreach (Area area in Area)
{
csv.Append(area.AreaID + ",");
csv.Append(area.AliasName + ",");
csv.Append(area.Description + ",");
csv.Append(area.BankName + ",");
csv.AppendLine();
}
return csv.ToString();
}
public void DownloadCsv()
{
using (Database db = new Database(_ConnectionString))
{
AreaDAC dacArea = new AreaDAC(db);
List<Area> data = dacArea.Search("", "", "");
string facsCsv = GetCsvString(data);
// Return the file content with response body.
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=Area.csv");
Response.Write(facsCsv);
Response.End();
}
}
I try to make like this also
public FileContentResult DownloadCsv()
{
using (Database db = new Database(_ConnectionString))
{
AreaDAC dacArea = new AreaDAC(db);
List<Area> data = dacArea.Search("", "", "");
JsonResult result = new JsonResult();
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
result.Data = data;
string facsCsv = GetCsvString(data);
return File(new System.Text.UTF8Encoding().GetBytes(facsCsv), "text/csv", "Area.csv");
}
}
I make also like this
public void DownloadCsv()
{
using (Database db = new Database(_ConnectionString))
{
AreaDAC dacArea = new AreaDAC(db);
List<Area> data = dacArea.Search("", "", "");
string facsCsv = GetCsvString(data);
// Return the file content with response body.
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=Area.csv");
Response.Charset = "";
Response.ContentType = "application/text";
Response.Output.Write(facsCsv);
Response.Flush();
Response.End();
}
}
But still not work.. No download CSV appear.. While When I got it all working, no error.
Now I already got the answer. I change the script like this and it's work..
var cd = new System.Net.Mime.ContentDisposition
{
FileName = "Area.csv",
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(new System.Text.UTF8Encoding().GetBytes(facsCsv), "text/csv");
It's work by adding new System.Net.Mime.ContentDisposition. But I'm still not understand why.
I was able to do using
window.location = "/urlPath?filename=" + filename;
and in my controller
filename = filename.ToString();
byte[] fileBytes = System.IO.File.ReadAllBytes(filename);
var response = new FileContentResult(fileBytes, "application/octet-stream");
response.FileDownloadName = "Filename.csv";
return response;
I am using ReportExecution2005.asmx service to execute report on report server and serve user with HTML of rendered report. I am setting the parameters programmatically but if i don't provider parameters, report crashes that parameter is not specified. What i want to do is to prompt the user for parameters if they are not provided. Prompt on parameters is on. Here is my source;
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://server/reportserver/ReportExecution2005.asmx";
// Render arguments
byte[] result = null;
string reportPath = "/Test reports/DemoReport";
string format = "HTML4.0";
string historyID = null;
string devInfo = #"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[2];
parameters[0] = new ParameterValue();
parameters[0].Name = "CompanyName";
parameters[0].Value = "ASDA";
parameters[1] = new ParameterValue();
parameters[1].Name = "ProgramID";
parameters[1].Value = "6";
DataSourceCredentials[] credentials = null;
string showHideToggle = null;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
ParameterValue[] reportHistoryParameters = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, historyID);
rs.SetExecutionParameters(parameters, "en-us");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
Console.WriteLine("SessionID: {0}", rs.ExecutionHeaderValue.ExecutionID);
try
{
result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
execInfo = rs.GetExecutionInfo();
Console.WriteLine("Execution date and time: {0}", execInfo.ExecutionDateTime);
}
catch (SoapException e)
{
Console.WriteLine(e.Detail.OuterXml);
}
// Write the contents of the report to an MHTML file.
try
{
FileStream stream = File.Create("report.mht", result.Length);
Console.WriteLine("File created.");
stream.Write(result, 0, result.Length);
Console.WriteLine("Result written to the file.");
stream.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Well, I already tried a lot of stuff to solve this issue, but none did.
I developed a Reporting Service (2005) and deployed it.
This report will be used by everyone who access a website (it's a internet site, so, won't be accessed by intranet) developed on the framework 3.5 (but I think the framework's version is not the source of the problem).
I had other issues with authentication, and the workaround included the using of the FileStream class on my website.
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://MyServer/ReportServer/ReportExecution2005.asmx";
arguments
byte[] result = null;
string reportPath = "/ReportLuiza/ReportContract";
string format = "PDF";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "NMB_CONTRACT";
parameters[0].Value = txtNmbContractReport.Text;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, null);
rs.SetExecutionParameters(parameters, "pt-br");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
execInfo = rs.GetExecutionInfo();
}
catch (SoapException se)
{
ShowMessage(se.Detail.OuterXml);
}
// Write the contents of the report to an pdf file.
try
{
using (FileStream stream = new FileStream(#"c:\report.pdf", FileMode.Create, FileAccess.ReadWrite))
{
stream.Write(result, 0, result.Length);
stream.Close();
}
}
catch (Exception ex)
{
ShowMessage(ex.Message);
}
For this code, I had to add a WebReference to the .asmx file mentioned in it.
Both Report and WebSite are deployed/published on the same server with a IIS 7.5 version.
Is there an way where user can choose where it wants to save the .pdf file?
Any help will be appreciated.
If you need more information to help me, just ask.
Thanks in advance.
You might want to combine the two try-catch blocks:
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
rs.Url = "http://MyServer/ReportServer/ReportExecution2005.asmx";
arguments
byte[] result = null;
string reportPath = "/ReportLuiza/ReportContract";
string format = "PDF";
// Prepare report parameter.
ParameterValue[] parameters = new ParameterValue[1];
parameters[0] = new ParameterValue();
parameters[0].Name = "NMB_CONTRACT";
parameters[0].Value = txtNmbContractReport.Text;
string encoding;
string mimeType;
string extension;
Warning[] warnings = null;
string[] streamIDs = null;
ExecutionInfo execInfo = new ExecutionInfo();
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
execInfo = rs.LoadReport(reportPath, null);
rs.SetExecutionParameters(parameters, "pt-br");
String SessionId = rs.ExecutionHeaderValue.ExecutionID;
try
{
result = rs.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
execInfo = rs.GetExecutionInfo();
}
catch (SoapException se)
{
ShowMessage(se.Detail.OuterXml);
}
// Write the contents of the report to an pdf file.
try
{
/*
using (FileStream stream = new FileStream(#"c:\report.pdf", FileMode.Create, FileAccess.ReadWrite))
{
stream.Write(result, 0, result.Length);
stream.Close();
}
*/
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=\"report.pdf\"");
Response.BinaryWrite(result);
Response.Flush();
Response.End();
}
catch (Exception ex)
{
ShowMessage(ex.Message);
}