I have the data that has to be loaded to an excel file in a byte array and I need to apply password protection on that.
I have tried converting byte[] to datatable/list and tried applying password protection using Excelpackage but I am not able to correctly convert data in byte[] array to any form.My file is getting downloaded but with some weired data. Can anyone please share your knowledge?
response.Clear();
response.Buffer = true;
response.ContentEncoding = System.Text.Encoding.UTF8;
response.ContentType = mimeType;
response.AddHeader("content-disposition", "attachment;filename="
+ Uri.EscapeDataString(fileName));
response.Charset = "";
response.Cache.SetCacheability(HttpCacheability.NoCache);
DataTable dt;
MemoryStream stream;
using (stream = new MemoryStream(fileBytes))
{
BinaryFormatter bin = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
dt = (DataTable)formatter.Deserialize(stream);
stream.Close();
}
using (ExcelPackage pack = new ExcelPackage())
{
ExcelWorksheet ws = pack.Workbook.Worksheets.Add("heelo");
ws.Cells["A1"].LoadFromDataTable(dt, true);
pack.Save("123");
var ms = new System.IO.MemoryStream();
pack.SaveAs(ms);
ms.WriteTo(HttpContext.Current.Response.OutputStream);
ms.Close();
}
response.Flush();
response.End();
Having a little trouble following you code. Why is response mime type a PDF? I think you would want that to be
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Does response actually have anything to do with the MemoryStreams since I see no reference from one to the other?
In any event, if you have the ExcelPackage available and you want to write to a Stream with a password, you can just call the overload:
pack.SaveAs(ms, "MyPassword")
Here is some more info: Password Protected Excel Download using EPPLUS
Related
I'm trying to save/download the .xlsx file that derive from memory stream like this way
public CustomObj SaveExcelFile(string sheetName)
{
var ret = new CustomObj();
MemoryStream memStream = new MemoryStream();
using (memStream = new MemoryStream())
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet(sheetName);
...
workbook.Write(memStream);
byte[] buffer = memStream.ToArray();
HttpContext.Current.Response.ContentType = "application/xlsx";
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=MyFile.xlsx");
HttpContext.Current.Response.BinaryWrite(buffer);
HttpContext.Current.Response.End();
}
return ret;
}
once I click the save file, this is supposed to download the file, but its doesn't give any error or save file. what did I miss here ?
I can generate the Pdf but I want to save the pdf in folder before show to the view.
I have read many articles but I did not find any proper solution.
Here is my code.
ReportDocument rd = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports"), "BillInformationReport.rpt"));
rd.SetDataSource(ds);
Stream stream = rd.ExportToStream(ExportFormatType.PortableDocFormat);
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms);
Byte[] fileBuffer = ms.ToArray();
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", fileBuffer.Length.ToString());
Response.BinaryWrite(fileBuffer);
rd.Close();
rd.Dispose();
return null;
I am trying to download .zip and .xlsx files from SFTP server,after downloading when I tried to open the zip file, it saying the compressed zip files is invalid and also the files size is high compared with the SFTP file size(remote file size).
I am using the below code :
string sFTPHost = "sftphost";
string sFTPDirectory = "file.zip";
string sFTPUser = "username";
string sFTPPassword = "pwd";
string sFTPPort = "22";
ConnectionInfo ConnNfo = new ConnectionInfo(#sFTPHost, Convert.ToInt32(sFTPPort), #sFTPUser,
new AuthenticationMethod[]{
new PasswordAuthenticationMethod(#sFTPUser,#sFTPPassword),
}
);
using (var sftp = new SftpClient(ConnNfo))
{
sftp.Connect();
MemoryStream ms = new MemoryStream();
sftp.DownloadFile(#sFTPDirectory, ms);
byte[] feedData = ms.GetBuffer();
var response = HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename="filename.zip");
response.AddHeader("Content-Length", feedData.Length.ToString());
response.ContentType = "application/octet-stream";
response.BinaryWrite(feedData);
sftp.Disconnect();
}
}
What could be the issue?
MemoryStream.GetBuffer returns the underlying array of the stream which can/will contain allocated, unused bytes. For example the length of the returned buffer will match the stream's current Capacity, but will most likely be larger than the stream's current Length.
From the documentation:
Note that the buffer contains allocated bytes which might be unused.
For example, if the string "test" is written into
the MemoryStream object, the length of the buffer returned
from GetBuffer is 256, not 4, with 252 bytes unused.
You will need to use ToArray instead. Note however that this creates a new array and copies the data into it.
byte[] feedData = ms.ToArray();
var response = HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=filename.zip");
response.AddHeader("Content-Length", feedData.Length.ToString());
response.ContentType = "application/octet-stream";
response.BinaryWrite(feedData);
Alternatively you should be able to copy from one stream to the other:
var response = HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=filename.zip");
response.AddHeader("Content-Length", ms.Length.ToString());
response.ContentType = "application/octet-stream";
// rewind stream and copy to response
ms.Position = 0;
ms.CopyTo(response.OutputStream);
I have tried the below coding for generating excel file on serverside.
C# CODING:
public void ReadandOpenExcel(DirectoryInfo outputDir)
{
//FileInfo newFile = new FileInfo(outputDir.FullName + #"\New Microsoft Excel Worksheet.xlsx");
var ExistFile = Server.MapPath("~/excelsample.xlsx");
var File = new FileInfo(ExistFile);
using (ExcelPackage package = new ExcelPackage(File))
{
package.Load(new FileStream(ExistFile, FileMode.Open));
ExcelWorksheet workSheet = package.Workbook.Worksheets["Sheet1"];
workSheet.Cells["A8"].Value = "kevin";
package.Save();
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", "attachment; filename=ProposalRequest.xslx");
**Response.BinaryWrite(package.GetAsByteArray());**
// myMemoryStream.WriteTo(Response.OutputStream); //works too
Response.Flush();
Response.Close();
}
}
While running the above code i got an error as : " Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package."
ERROR On This Line:
Response.BinaryWrite(package.GetAsByteArray());
Make some way for this coding to move on.
Thanks in advance.
Does it work if you get the bytes before you do the Save ?
Byte[] bin = package.GetAsByteArray();
package.Save();
And then use that value in the Binarywrite;
Response.BinaryWrite(bin);
Maybe it is getting closed on the .Save() call ?
When I try to generate an Excel file using EPPlus, Excel give me the following error message:
Excel cannot open the file 'myfilename.xlsx' because the file format or file extension is not valid. Verify the the file has not been corrupted and that the file extension matches the format of the file.
Here's my code:
public ActionResult Index()
{
using (ExcelPackage package = new ExcelPackage())
{
// I populate the worksheet here. I'm 90% sure this is fine
// because the stream file size changes based on what I pass to it.
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
var cd = new System.Net.Mime.ContentDisposition
{
Inline = false,
FileName = fileName
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(stream, contentType, fileName);
}
}
Any idea what I'm doing wrong?
All you need to do is reset the stream position. stream.Position = 0;
You shouldn't write directly to the Response, it's not the MVC way. It doesn't follow the correct MVC pipeline and it tightly couples your controller action code to the Response object.
When you add a file name as the 3rd parameter in File(), MVC automatically adds the correct Content-Disposition header... so you shouldn't need to add it manually.
The short of it is, this is what you want:
public ActionResult Index()
{
using (ExcelPackage package = new ExcelPackage())
{
// I populate the worksheet here. I'm 90% sure this is fine
// because the stream file size changes based on what I pass to it.
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
Your code doesn't show stream being written to the HttpResponse - presumably being done in the File method which you haven't posted.
One way that does work is the following:
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader(
"content-disposition", String.Format(CultureInfo.InvariantCulture, "attachment; filename={0}", fileName));
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
Similar to Joe's answer, I still had to call Response.ClearHeaders():
protected void btnDownload_Click(object sender, EventArgs e)
{
ExcelPackage pck = new ExcelPackage();
var ws = pck.Workbook.Worksheets.Add("Sample2");
ws.Cells["A1"].Value = "Sample 2";
ws.Cells["A1"].Style.Font.Bold = true;
var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
shape.SetPosition(50, 200);
shape.SetSize(200, 100);
shape.Text = "Sample 2 outputs the sheet using the Response.BinaryWrite method";
Response.Clear();
Response.ClearHeaders();
Response.BinaryWrite(pck.GetAsByteArray());
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=Sample2.xlsx");
Response.End();
}