Save as using EPPlus? - c#

Does any one know how to use the package.Saveas function?
package.SaveAs(tempFolderPathAlt + saveas + ".xlsx");
At the moment this is underlined in red with the following error:
The best overloaded method match for
'OfficeOpenXml.ExcelPackage.SaveAs(System.IO.Stream)' has some invalid
arguments
At the moment i'm saving the file in the following way.
FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xls", FileMode.Create);
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0, byData.Length);
aFile.Close();
But this way the package remains open and i cant work with files it has used.
The save as will close the package properly, but its not accepting my file path.
Edit
I tried this:
using (FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xlsx", FileMode.Create))
{
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
//aFile.Write(byData, 0, byData.Length);
aFile.Close();
}
But Get the following error?
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.

The package will be closed & disposed after you call any of functions GetAsByteArray, Save, SaveAs. That is the reason why you got message
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.
The solution is that after the saving you call Load function to continue processing on excel file. Or if you just want to get both ByteArray & FileOutput, I'm sure with you they both are same.
You can read data after have saved file to the disk:
string path = #"C:\test1.xlsx";
Stream stream = File.Create(path);
package.SaveAs(stream);
stream.Close();
byte[] data = File.ReadAllBytes(path);
Or you can save data to disk after get the ByteArray:
byte[] data = package.GetAsByteArray();
string path = #"C:\test1.xlsx";
File.WriteAllBytes(path, data);

I came looking for the answer to this but the existing answers were not clear to me.
Here is what I did using EPPlus and System.Windows.Forms:
ExcelPackage xlPackage = new ExcelPackage(xlsTmpFileName)
// Populate the Excel spreadsheet here.
SaveFileDialog sfd = new SaveFileDialog();
using (FileStream fs = new FileStream(sfd.FileName, FileMode.Create))
{
xlPackage.SaveAs(fs);
}

I dont know from which version onwards but EPPlus's SaveAs method accepts a FileInfo. So you could do something like this:
using (var app = new ExcelPackage(new FileInfo(inputPath)))
{
//process
app.SaveAs(new FileInfo(outputPath));
}
Unlike the Save method SaveAs method overwrites file as well in case file name already exists.

SaveAs would be accepting your aFile Stream.
You can find out such things yourself by looking at the function signature: SaveAs(System.IO.Stream). It takes a Stream. Passing a string cannot possibly compile so you have to somehow make up a useful Stream (which you did).

Get rid of the surplus package.GetAsByteArray call and you should solve it.
I just ran:
using (FileStream aFile = new FileStream(#"C:\Temp\asdf.xlsx", FileMode.Create))
{
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
aFile.Close();
}
// See here - I can still work with the spread sheet.
var worksheet = package.Workbook.Worksheets.Single();

Related

How to close FileStream without causing an error in "Syncfusion.PdfViewer"?

I'm using Syncfusion.PdfViewer in my project. When I click an item in a list, the related pdf file is loaded and shown in the PdfViewer:
private void PdfReport(string address)
{
//Load the stream from the local system.
FileStream fs = new FileStream(address, FileMode.Open);
PdfSource = fs;
}
The problem is that each time I load a pdf file, a new instance of FileStream is created and the memory usage increases. When I try to close FileStream like the following code, the pdf is not shown in the viewer:
private void PdfReport(string address)
{
//Load the stream from the local system.
FileStream fs = new FileStream(address, FileMode.Open);
PdfSource = fs;
fs.Dispose();
}
How can I solve this problem?
You should check if a PdfSource exists and if so close/ dispose that before creating the new filestream, so just
if (PdfSource is not null)
PdfSource.Dispose();
PdfSource = new FileStream(address, FileMode.Open);
In Syncfusion PDFViewer, while loading the PDF document as stream/file, it unloads the existing loaded document internally. While unloading the document, it will dispose the file stream. Hence, we don’t need to dispose the file stream on the sample side.

How do I save a file stream straight to an excel file in C#? [duplicate]

This question already has an answer here:
OPEN XML to Export 2007/2010
(1 answer)
Closed 3 years ago.
To give you a bit of context I'm trying to download a bunch of attachments in one bulk operation. These attachments are normally downloaded via a website a file at a time and the MVC controller code which retrieves the attachment looks something like this:
var attachment = _attachmentsRepository.GetAttachment(websiteId, id);
if (attachment.FileStream == null || !attachment.FileStream.CanRead)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
var content = new StreamContent(attachment.FileStream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = $"{id}.{attachment.Extension}" };
return new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
What I'm trying to do is write a console application for the bulk operation which will save each file directly to disk and sofar what I've got for a single file save is:
var = attachment attachmentsRepository.GetAttachment(websiteId, resource.Id);
attachment.FileStream.Position = 0;
var reader = new StreamReader(attachment.FileStream);
var content = reader.ReadToEnd();
File.WriteAllText(someFilePath, content);
I've side-stepped any http specific framework classes since I just need to download directly to file via code instead of the browser. This code successfully generates files but when I open them Excel indicates that they're corrupted which I suspect is an encoding issue. I'm currently playing around with the encoding at the moment but sofar not much luck so any help is appreciated.
Don't use StreamReader for processing binary data. The StreamReader/StreamWriter classes are for reading and writing human-readable text in a Stream and as such they attempt to perform text encoding/decoding which can mangle binary data (I feel the classes should be renamed to StreamTextReader/StreamTextWriter to reflect their inheritance hierarchy).
To read raw binary data, use methods on the Stream class directly (e.g. Read, Write, and CopyTo).
Try this:
var attachment = ...
using( FileStream fs = new FileStream( someFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 8 * 1024, useAsync: true ) )
{
await attachment.FileStream.CopyToAsync( fs );
}
The using() block will ensure fs is flushed and closed correctly.

Nancy httpfile issue

i have problems during parsing request files.
my file size is 1338521 bytes, but Nancy says, that file size is some times 1751049 or 3200349.
on my windows pc it works fine, on linux server this problem appears, so i can't save file.
string result = Convert.ToBase64String(Core.ReadBytesFromStream(file.Value));
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(result)))
{
using (Bitmap bm2 = new Bitmap(ms))
{
bm2.Save(path);
}
}
any ideas?
You don't need to convert the file like that.
var filename = Path.Combine(storagePath, Request.Files[0].Name);
using (var fileStream = new FileStream(filename, FileMode.Create))
{
Request.Files[0].Value.CopyTo(fileStream);
}
Validate the file when it comes in to ensure the extension is accepted, create a save path, and copy the stream to a new file on the filesystem.
That's it.

How to save a file from database to server

Question is rather simple, and somewhat pointless I understand, but still...
Database is on the server, of course, and I need an action that will when initiated grab that file from database and save it to a folder that is in my AppSettings["Active"] configuration property.
Basically,
public ActionResult Activate(int id)
{
Project project = db.Projects.Find(id);
var activeProjectData = project.XML; // project.XML returns byte[] type
//For download (not in this method of course) i'm using something like return File(activeProjectData, "text/xml"); and that works ok
}
Now I want to save that file to AppSettings["Active"] path. Not to sure how to go about it. I've tried using System.IO.File.Create() but that didn't quite turn out well.
Any help is appreciated.
Simply create a FileStream and use it to write the data:
string fileName = ConfigurationManager.AppSettings["Active"];
using(var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write) )
{
fs.Write(project.XML, 0, project.XML.Length);
}
If you don't need more control than that, there is a simple helper method on the File class:
File.WriteAllBytes(fileName, project.XML);
You'll need to use a FileStream
SqlCommand ("select fileBin from SomeTable", connection);
byte[] buffer = (byte[]) command.ExecuteScalar ();
connection.Close();
FileStream fs = new FileStream(#"C:\filename.pdf", FileMode.Create);
fs.Write(buffer, 0, buffer.Length);
fs.Close();

GZipStream works but extension is lost

I am using following code to zip a file and it works fine but when I decompress with WinRar I get the original file name without the extension, any clue why if filename is myReport.xls when I decompress I get only myReport ?
using (var fs = new FileStream(fileName, FileMode.Open))
{
byte[] input = new byte[fs.Length];
fs.Read(input, 0, input.Length);
fs.Close();
using (var fsOutput = new FileStream(zipName, FileMode.Create, FileAccess.Write))
using(var zip = new GZipStream(fsOutput, CompressionMode.Compress))
{
zip.Write(input, 0, input.Length);
zip.Close();
fsOutput.Close();
}
}
GZip compresses only one file - without knowing the name. Therefore if you compress the file myReport.xls you should name it myReport.xls.gz. On decompression the last file extension will be removed so you end up with the original filename.
That its the way how it is used in Unix/Linux for ages...
Very weird indeed. A brief search came up with the following:
http://dotnetzip.codeplex.com/discussions/268293
Which says that GZipStream has no way of knowing the name of the stream that is being written, and suggests you set the FileName property directly.
Hope that helps.

Categories

Resources