I'm trying to add button to Users Maintenance and on button's click download excel file, containing some data. I have created PXAction and it's method as above:
public PXAction<Users> getUsers;
[PXUIField(DisplayName = "Get Users", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select,Visible = true), PXButton(CommitChanges = true)]
public IEnumerable GetUsers(PXAdapter adapter)
{
var accessByRoles = PXSelect<RolesInGraph>.Select(this.Base);
var usersByRole = PXSelect<UsersInRoles>.Select(this.Base);
var dt = GetTable();//GetTable returns some DataTable just for test now
XLWorkbook workbook = new XLWorkbook();
workbook.Worksheets.Add(dt, "UserAccessRigths");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
workbook.SaveAs(MyMemoryStream);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=\"UserAccessRigths.xlsx\"");
HttpContext.Current.Response.AppendHeader("Content-Length", MyMemoryStream.ToArray().Length.ToString());
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.BinaryWrite(MyMemoryStream.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
return null;
}
Everything work but the part where the download in the browser must start.
I'm getting as response the excel, but it's not being downloaded.
Here is the response I'm getting in the browser:
I will be very grateful if someone can help me.
Thanks in advance
Try PXRedirectToFileException to redirect the user browser to the Excel file. Default behavior from mainstream browser is to detect Excel mime type by extension and initiate a download. Second parameter of PXRedirectToFileException is used to force download.
throw new PXRedirectToFileException(new PX.SM.FileInfo(Guid.NewGuid(),
"UserAccessRigths.xlsx",
null,
MyMemoryStream.ToArray()),
true);
Related
I want to make a button that makes the download of a DataTable object using an HTTP request.
I already have this code that can print .xls files by changing the contentType as indicated in comment.
However, this does not work with xlsx file.
private void DownloadExcel(DataSet ds, string excelFileNameNowDateTime)
{
System.IO.StringWriter tw = new System.IO.StringWriter(); ;
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
System.Web.UI.WebControls.DataGrid dgGrid = new System.Web.UI.WebControls.DataGrid();
dgGrid.DataSource = ds.Tables[0];
// Get the HTML for the control.
dgGrid.HeaderStyle.Font.Bold = false;
dgGrid.DataBind();
dgGrid.RenderControl(hw);
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//string contentType = "application/vnd.ms-excel";
Response.ContentType = contentType;
this.EnableViewState = true;
Response.Clear();
//Response.ContentEncoding = System.Text.Encoding.Default;
Response.AddHeader("content-disposition", String.Format(#"attachment; filename={0}", excelFileNameNowDateTime + ".xlsx"));
Response.Write(tw.ToString());
CloseHTTPResponse();
}
While opening the file is giving me the error
Excel cannot open the file .xlsx because the file format is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.
Any idea on why this does not work?
It looks to me like you're trying to send HTML contents with .xlsx extension. This won't work since XLSX is fundamentally not HTML, but zipped XML with quite specific (and convoluted) schema. The simplest way to achieve your goal would be to use one of the existing 3rd party libraries that can generate XLSX on the fly. I personally had used ClosedXML for a similar task, but there are many other options at NuGet.
This code doesn't produce an Excel file, it produces an HTML file with a fake extension. Excel won't be fooled, it will try to import this HTML file using the user locale's defaults. This will easily lead to problems if the decimal separator is different or the cells contain text that interferes with HTML.
There's no reason for such code. XLSX is a ZIP package containing well-formed XML files. You can use the Open XML SDK to create Excel files at a low level or you can use libraries like EPPlus (57M downloads), ClosedXML (27M), NPOI (22M) and more, to create real Excel files.
With EPPlus, creating an Excel file from a DataTable is really a single command, sheet.Cells.LoadFromDataTable(dt);
public byte[] Export(DataTable dt)
{
using (var p = new ExcelPackage())
{
var ws = p.Workbook.Worksheets.Add("SomeSheet");
var table=ws.Cells.LoadFromDataTable(dt);
var excelData = package.GetAsByteArray();
return excelData;
}
}
After that, you write the output to the Response stream :
var bytes = Export(dt);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", $"attachment;filename={excelFileNameNowDateTime}.xlsx");
Response.BinaryWrite(bytes);
Response.End();
For ASP.NET (no .NET Core Required solution).
using ClosedXML.Excel;
private void DownloadExcelClosedXML(DataTable dt)
{
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add(dt);
using (var stream = new MemoryStream())
{
workbook.SaveAs(stream);
var content = stream.ToArray();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheet.sheet";
Response.AddHeader("content-disposition", "attachment; filename=name_you_file.xlsx");
Response.BinaryWrite(content);
Response.End();
}
}
}
I want to display a pdf. My current code displayit using a pdf reader. But I want to open it in a seperate tab of the browser. How can i do it? I have a link button inside the web page. I have set this in onClick method. How to open it using back end code? (not using a link in aspx)
Here is my code
string name = ddlAppealList.SelectedValue.ToString();
int refNo = Convert.ToInt32(name);
string FilePath = Server.MapPath("~/filesPDF/" + refNo + ".pdf");
WebClient User = new WebClient();
Byte[] FileBuffer = User.DownloadData(FilePath);
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
}
Response.ContentType = "Application/pdf";
Response.TransmitFile(PDFfilepath);
For opening the PDF file in a new tab or windows you can use following html code:
View
I hope it helps you.
I encountered a similar situation a few weeks ago. This piece of code, inspired by this answer, helped me solve the issue:
Response.AppendHeader("Content-Disposition", new System.Net.Mime.ContentDisposition { Inline = true, FileName = "pdfname.pdf" }.ToString());
Here is an example to open a pdf in a C# web application with ActionResult. You can also store the pdf as a byte[] in the database to make this code simpler.
public async Task<ActionResult> ViewPdf()
{
MemoryStream ms = new MemoryStream();
FileStream stream = new FileStream("mypdf.pdf", FileMode.Open, FileAccess.Read);
stream.CopyTo(ms);
return File(ms.ToArray(), "application/pdf");
}
I have got the below method that will do export to excel, My aim is when I click the link on web page I need to export the data from kendo ui grid to excel along with that asp.net MVC4 for that purpose I have written below method.....
the below method is action method that will call when I click exporttoexcel action link on view
public ActionResult ExportToExcel()
{
byte[] file;
string targetFilename = string.Format("{0}-{1}.xlsx", "Generated", "excel");
DataTable dt = common.CreateExcelFile.ListToDataTable(GetSearchDraftPRResults());
common.CreateExcelFile excelFileForExport = new CreateExcelFile();
file = excelFileForExport.CreateExcelDocumentAsStream(dt, targetFilename);
Response.Buffer = true;
return File(file, "application/vnd.ms-excel", targetFilename);
}
and the below method is for creating excel document
public byte[] CreateExcelDocumentAsStream(DataTable dt, string filename)
{
DataSet ds = new DataSet();
ds.Tables.Add(dt);
System.Web.HttpResponse Response = null;
System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (SpreadsheetDocument document = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook, true))
{
WriteExcelFile(ds, document);
}
stream.Flush();
stream.Position = 0;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.AddHeader("content-disposition", "attachment; filename=" + filename);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
byte[] data1 = new byte[stream.Length];
stream.Read(data1, 0, data1.Length);
return stream.ToArray();
}
but when I click the action link I am getting error NullReferenceexpection at this line
Response.Clear();
I am not sure why I am getting this this exception and I am using open xml dll for export to excel
I am not sure about this procedure, Is this is right way for export to excel functionality .. would any one pls guide me in correct direction ...
Would any one please help on this that would be very grateful to me
many Thanks in advance....
You really don't need to mess with Response in the CreateExcelDocumentAsStream() method. As the name implies, the only responsibility of the method is to create the Excel file and return it as a byte[] array.
It's the (MVC) Action responsibility then to set the appropriate response headers and behavior to accommodate the client (Web Browser, in this case) needs.
Also, when you return a FileResult, it takes care of setting the Http response, no Response.Clear() or Response.Buffer needed in the Action as well.
I have this code for creating an Excel file and then sending it for download:
Stream stream = Stream.Null;
using (ExcelDocument doc = ExcelDocument.CreateWorkbook(stream))
{
ExcelWorksheet wsheet = doc.Workbook.Worksheets.Add("Assessment");
doc.EnsureStylesDefined();
// add some cells
}
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "inline;filename=Assessment.xlsx;charset=utf-8;");
Response.BinaryWrite(Utilities.Utilities.ConvertFileToByteArray(stream));
Response.End();
When it gets to end of the using, I get this error :
File contains corrupted data.
If I save file to my disk it works fine.
where I went wrong?
I'm using this Component.
change first line to :
MemoryStream stream = new MemoryStream();
Also Change
Response.BinaryWrite(Utilities.Utilities.ConvertFileToByteArray(stream));
to
Response.BinaryWrite(stream.ToArray());
I Tried a few solutions mentioned in the site like Using System.Microsoft.Office.Excel and Excel = System.Microsoft.Office.Excel, but it dint work....
Here, I'm trying to get the data in a table and download to a file in the specified location in the server in .xls format and then giving the users a link to download the file.
this is the code for export `
protected void btnExcelExport_Click(object sender, EventArgs e)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using( HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// Create a form to contain the grid
Table table = new Table();
// get gridlines from gridview
table.GridLines = GridView2.GridLines;
if (GridView2.HeaderRow != null)
{
table.Rows.Add(GridView2.HeaderRow);
}
foreach (GridViewRow row in GridView2.Rows)
{
table.Rows.Add(row);
}
if (GridView2.FooterRow != null)
{
table.Rows.Add(GridView2.FooterRow);
}
// render the table into the htmlwriter
table.RenderControl(htw);
}
var myRootPath = Server.MapPath("~");
var docPath = Path.GetFullPath(Path.Combine(myRootPath, "/Compare/c.xls"));
File.WriteAllText(docPath, sw.ToString());
}
dwndlink.Visible = true;
}
And when this is code for linkbutton:
protected void dwnlink(object sender, EventArgs e)
{
var webRootPath = Server.MapPath("~");
var docPath = Path.GetFullPath(Path.Combine(webRootPath, "/Compare/c.xls"));
string name = Path.GetFileName(docPath);
Response.AppendHeader("content-disposition", "attachment; filename=" + name);
Response.ContentType = "Application/vnd.ms-excel";
Response.TransmitFile(docPath);
Response.End();
}
so when the user opens the downloaded file, gives a warning as its not in the same extension.
Why is this happening..??
I tried working with the solutions provided in various sites, but to no avail...
Thanks
try using
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
Try changing Response.ContentType = "application/vnd.xls"; to Response.ContentType = "application/vnd.ms-excel"
Also
Microsoft document says :
"The current design does not allow you to open HTML content from a web site in Excel... So ASP pages that return HTML and set the MIME type to something like XLS to try to force the HTML to open in Excel instead of the web browser (as expected) will always get the security alert... If you use an HTML MIME type, then the web browser will open the content instead of Excel. So there is no good workaround for this case because of the lack of a special MIME type for HTML/MHTML that is Excel specific. You can add your own MIME type if you control both the web server and the client desktops that need access to it, but otherwise the best option is to use a different file format or alert your users of the warning and tell them to select Yes to the dialog."
Visit this site too : http://devblog.grinn.net/2008/06/file-you-are-trying-to-open-is-in.html