I'm currently developing a simple program (using ASP.Net C#) to populate data from GridView into Excel file. the Excel file will be need to downloaded into client computer.
For some reasons, I need to manipulate the Excel file quickly after it downloaded into client local computer.
The problem is I can't get the file location where the file was downloaded.
How can I get the file location after it downloaded into client computer ?
This is the screenshot:
Download Code:
private void Create_ExcelContent2()
{
Response.Clear();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment;filename=" + ddlBatchID.Text + ".xls");
Response.Charset = "";
Response.ContentType = "application/vnd.ms-excel";
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw); ...
gvBatchSummary.RenderControl(hw);
string style = #"<style> .textmode { } </style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
}
The short answer to this is you cannot do it. Once the file is on the local machine server side code cannot be use to manipulate it. If you could the security implications would be a mine field.
why don't you try as below
string folderPath = string.Empty;
using (FolderBrowserDialog fdb = new FolderBrowserDialog()) {
if (fdb.ShowDialog() == DialogResult.OK ){
folderPath = fdb.SelectedPath;
}
}
sorry i didn't seen it #fubo ,
Edit:
if at all you want that directory path, then why don't you save it to a prefixed local system path, and from there you can read it and manipulate it.
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'm trying to use EPPlus to create a report inside an ASP.NET application. I tried using the code provided into samples package but I'm having some troubles.
The following code is executed without error:
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample1");
_ws.Cells["A1"].Value = "COD. CONV.";
_ws.Cells["A1"].Style.Font.Bold = true;
_ws.Cells["A1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["B1"].Value = "RAGIONE SOCIALE";
_ws.Cells["B1"].Style.Font.Bold = true;
_ws.Cells["B1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["C1"].Value = "COMMERCIALE A";
_ws.Cells["C1"].Style.Font.Bold = true;
_ws.Cells["C1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["D1"].Value = "PROVINCIA";
_ws.Cells["D1"].Style.Font.Bold = true;
_ws.Cells["D1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["E1"].Value = "ZONA";
_ws.Cells["E1"].Style.Font.Bold = true;
_ws.Cells["E1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["F1"].Value = "TELEFONO";
_ws.Cells["F1"].Style.Font.Bold = true;
_ws.Cells["F1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
_ws.Cells["G1"].Value = "EMAIL";
_ws.Cells["G1"].Style.Font.Bold = true;
_ws.Cells["G1"].Style.Border.Bottom.Style = OfficeOpenXml.Style.ExcelBorderStyle.Thick;
int _i = 2;
foreach (DataRow _drRow in dtAnagrafiche.Rows)
{
_ws.Cells["A"+_i.ToString()].Value = _drRow["codice"].ToString();
_ws.Cells["B"+_i.ToString()].Value = _drRow["Nome"].ToString();
_ws.Cells["C"+_i.ToString()].Value = "";
_ws.Cells["D"+_i.ToString()].Value = _drRow["Provincia"].ToString();
_ws.Cells["E"+_i.ToString()].Value = _drRow["Zona"].ToString();
_ws.Cells["F"+_i.ToString()].Value = _drRow["Telefono"].ToString();
_ws.Cells["G"+_i.ToString()].Value = _drRow["Email"].ToString();
_i++;
}
Response.BinaryWrite(_pck.GetAsByteArray());
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=Lista_Anagrafiche.xlsx");
but the resulting file cannot be opened by Microsoft office if not 'recovered', other MS Office compatibile applications (i.e. OpenOffice) cannot open the file.
I can provide the output file if needed.
https://drive.google.com/file/d/0B-lPXYt7laDrbUFKbFZEWEwxckk/view?usp=sharing
BTW I'm using the last (4.0.5) EPPlus package obtained trough nuget, and running it in ASP.NET 4.5 web appplication.
You're missing a call to Response.End(). Without this, you're sending the response with the binary payload (the .xlsx file), which is coming over correctly, then the .aspx page that you're coding this under is being sent in the payload as well. Proof here as shown in a hex editor.
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=Lista_Anagrafiche.xlsx");
Response.BinaryWrite(_pck.GetAsByteArray());
Response.End();
Should do the trick.
As an aside, I would suggest saving the file, then doing a Response.Redirect() to the URL of the file, instead, but that's unrelated to this specific issue.
EDIT: Notably, in normal circumstances, I would suggest avoiding Response.End(), but, that is the quickest way to solve the problem you've coded yourself into. I would suggest looking for better ways to serve up these files in general, as per my above suggestion to Response.Redirect() to a saved location of the file.
Try changing your code to the following notice how I am using the string.Format function to create the filename + extension
you need to declare a constant fileName. if worse comes to worse change the .xlsx to .xls
Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("Content-Disposition", string.Format("attachment;filename={0}.xlsx", fileName));
Response.BinaryWrite(_pck.GetAsByteArray());
Response.Flush();
Response.End();
I'm searching how to open a document with word, without its path.
I get my document like this :
byte[] text = item.Doc;
The document comes directly from database.
I only found way to open with a path... So with my doc, I must open it, and then run saveAs of word application (choice between pdf, doc etc...).
I can store it in a MemoryStream, but, what can I do with it next?
Found this How to open a file from Memory Stream, but not helping me.
try this
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/ms-word";
string fileName = "Test.doc";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
StreamReader reader = new StreamReader(memoryStream, System.Text.Encoding.UTF8, true);
string strContents = reader.ReadToEnd();
Reader.Close();
Response.Write(strContents);
Response.End();
--SJ
Is it possible to save an exported word document file using Response.Write(). Now it's showing Save/Open dialog box, once it Converted successfully. But i need to save this file to a folder. Please help me for resolve this issue.
My conversion to Doc code is appended below.
private void ExportDataSetToWordDoc()
{
try
{
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", DateTime.Today.ToShortDateString().Replace("/", "").Replace("-", "") + "_" + DateTime.Now.ToShortDateString() + ".doc"));
Response.ContentType = "application/ms-word";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
tblMain.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}
catch (ThreadAbortException ex)
{
Common.LogError(ex);
}
}
It's up to the Browser to offer the user an "open or save" option. That's what your content-disposition "attach" is encouraging the browser to do. Your other option is content-disposition "inline", where the browser will usually just call up the application (Word in this case) to open the file. See MSDN.
Sadly, the browser will not always offer the filename you specified as the default filename in the "Save As" dialog. Often it will offer the name of your web page as the default instead. Firefox at least documents this as a bug, IE seems to think it is a "feature".
I have modified my code as shown below. Now its saving the specified folder
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", DateTime.Today.ToShortDateString().Replace("/", "").Replace("-", "") + "_" + DateTime.Now.ToShortDateString() + ".doc"));
Response.ContentType = "application/ms-word";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
tblMain.RenderControl(htw);
string strPath = Request.PhysicalApplicationPath + "Test.doc";
StreamWriter sWriter = new StreamWriter(strPath);
sWriter.Write(sw.ToString());
sWriter.Close();
Thanks.
You can use a stream writer (System.IO.StreamWriter) using a path.
When the stream writer will be closed, the file will be saved on at the specified path.
But, it will save on the server disk. If you want to save on the client side, you don't have other choice than ask the user where to put the file. You can't save files on a client without its approval.
var x = new System.IO.StreamWriter(path);
x.Close();
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