Convert byte[] to excel file (xlsx) - c#

I need to convert a byte array into an excel file using C# to upload it in Sharepoint.
The following code read an input file from client as a byte array:
public object UploadFile(HttpPostedFile file)
{
byte[] fileData = null;
using (var binaryReader = new BinaryReader(file.InputStream))
{
fileData = binaryReader.ReadBytes(imageFile.ContentLength);
// convert fileData to excel
}
}
How can I do it?

It sounds like you're just after File.WriteAllBytes(path, contents). However, if the input file could be large, you may be better off using the Stream API:
using(var destination = File.Create(path)) {
file.InputStream.CopyTo(destination);
}
Edit: it looks like HttpPostedFile has a SaveAs method, so just:
file.SaveAs(path);

Related

convert compress xmldocument as zip and get as byte array

I am building a XmlDocument in memory (I am not writing it to disk). I need to be able to create a zip archive that would contain the Xml file and then get the zip archive as byte array (all of this without actually writing/creating anything on the hard-disk). Is this possible?
I should mention that I am trying to do this in C#.
var buffer = new MemoryStream();
using (buffer)
using (var zip = new ZipArchive(buffer, ZipArchiveMode.Create) )
{
var entry = zip.CreateEntry("content.xml", CompressionLevel.Optimal);
using (var stream = entry.Open())
{
xmlDoc.Save(stream);
}
}
var bytes = buffer.ToArray();

How to create and send ZIP archive from C# to Python and save to filesystem?

In C# I create zip archive with some files:
using (MemoryStream ms = new MemoryStream())
{
using (ZipStorer zip = ZipStorer.Create(ms, "comment"))
{
zip.EncodeUTF8 = true;
foreach (FileInfo logFile in logFiles)
{
zip.AddFile(ZipStorer.Compression.Deflate, logFile.FullName, logFile.Name, "");
}
}
this.logger.log("memory stream to array");
zipBytesArr = ms.ToArray();
}
It works, because when I persist zip archive on server with C# - I can open it.
File.WriteAllBytes("C:\\test.zip", zipBytesArr);
Now I send it as bytes array zipBytesArr in POST request, I create object with field type byte[], than serialise it to JSON and send.
MyObject myObject = new MyObject()
{
// .. some fields
ZipFileBytesArr = ZipFileBytesArr
};
var json = JsonConvert.SerializeObject(myObject);
Now I want to get it in Python 3 (flask), I got some long string and I want to create zip archive. My question is: how to achieve this?
I tried something like this:
bytes_as_str = "UEsDBBQAAAgIACyrWk4qVSmD0gYAAA4WAAAYAAAAMjAxOTAyMjZfb3BlbnZ...."
bytes_as_bytes = bytes_as_str.encode(encoding="utf-8")
file = zipfile.ZipFile(io.BytesIO(bytes_as_bytes))
and it does not work, I got an error:
zipfile.BadZipFile: File is not a zip file

Convert object to CSV and then compress without touching physical storage

Scenario
I have a object that I convert to a flat CSV and then compress and upload to a filestore.
I could easily do this by following the below steps.
Convert object to CSV file.
Compress file
Upload file.
However
I do not want the penalty that comes with touching physical storage so would like to do all this in memory.
Current Incorrect Implementation
Convert object to CSV byte array
Compress byte array
Upload byte array to file store
Problem
What i'm essentially doing is compressing a byte array and uploading that. which is obviously wrong. (Because when the compressed Gzip file is uncompressed, it contains a byte array of the csv and not the actual csv itself.)
Is it possible to create a file like "file.csv" in memory and then compress that in memory, instead of compressing a byte array?
The problem I'm having is it would seem I can only name the file and specify its extension when saving to a physical location.
Code Example of Current Implementation
public byte[] Example(IEnumerable<object> data)
{
// Convert Object to CSV and write to byte array.
byte[] bytes = null;
using (var ms = new MemoryStream())
{
TextWriter writer = new StreamWriter(ms);
var csv = new CsvWriter(writer);
csv.WriteRecords(data);
writer.Flush();
ms.Position = 0;
bytes = ms.ToArray();
}
//Compress byte array
using (var compressedStream = new MemoryStream(bytes))
using (var resultStream = new MemoryStream())
using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
{
zipStream.CopyTo(resultStream);
zipStream.Close();
var gzipByteArray = resultStream.ToArray();
//Upload to AzureStorage
new AzureHelper().UploadFromByteArray(gzipByteArray, 0, gzipByteArray.Length);
}
}
Wrap the Stream you use for the upload in a GZipStream, write your CSV to that, and the then you'll have uploaded the compressed CSV.

It does not appear to be a valid archive (Byte array to zip file in c#.net)

I am facing issue while converting byte array to zip file.Even though zip file is created using the below code but when I am extracting the zip file I am getting error "Cannot open file. It does not appear to be a valid archive".
private static void ShowZipFile(string fileName, byte[] data)
{
byte[] compress = Compress(data);
File.WriteAllBytes(fileName, compress);
}
private static byte[] Compress(byte[] data)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory,
CompressionMode.Compress, true))
{
gzip.Write(data, 0, data.Length);
}
return memory.ToArray();
}
}
A GZipStream isn't a zip file, basically - it's a gzip file. That's just compressed data, without any notions of multiple files, file names etc. If you save the file as foo.gz you may find that the zip tool you use knows how to decompress that, but you definitely need to understand that it's not the same as a foo.zip with file entries etc.
If you want to create an actual zip file, you might want to look at SharpZipLib, System.IO.Compression.ZipFile or similar libraries.

Is it possible to change file content directly in zip file?

I have form with text box and customer wants to store all changes from this textbox to zip archive.
I am using http://dotnetzip.codeplex.com
and i have example of code:
using (ZipFile zip = new ZipFile())
{
zip.AddFile("text.txt");
zip.Save("Backup.zip");
}
And i dont want to create each time temp text.txt and zip it back.
Can I access text.txt as Stream inside zip file and save text there?
There is an example in DotNetZip that use a Stream with the method AddEntry.
String zipToCreate = "Content.zip";
String fileNameInArchive = "Content-From-Stream.bin";
using (System.IO.Stream streamToRead = MyStreamOpener())
{
using (ZipFile zip = new ZipFile())
{
ZipEntry entry= zip.AddEntry(fileNameInArchive, streamToRead);
zip.Save(zipToCreate); // the stream is read implicitly here
}
}
A little test using LinqPad shows that it is possible to use a MemoryStream to build the zip file
void Main()
{
UnicodeEncoding uniEncoding = new UnicodeEncoding();
byte[] firstString = uniEncoding.GetBytes("This is the current contents of your TextBox");
using(MemoryStream memStream = new MemoryStream(100))
{
memStream.Write(firstString, 0 , firstString.Length);
// Reposition the stream at the beginning (otherwise an empty file will be created in the zip archive
memStream.Seek(0, SeekOrigin.Begin);
using (ZipFile zip = new ZipFile())
{
ZipEntry entry= zip.AddEntry("TextBoxData.txt", memStream);
zip.Save(#"D:\temp\memzip.zip");
}
}
}
There is another DotNetZip method accepting a file path as an argument:
zip.RemoveEntry(entry);
zip.AddEntry(entry.FileName, text, ASCIIEncoding.Unicode);

Categories