I need to generate multiple .CSV
files from an object and then zip all the files.
This is what I got, I can't make a way to split the .csv
file in 2 if it's needed, and the .csv
file is broken, I got a lot of text errors in it that wasn't on the list...
What is the best approach to do this? Am I close to the right thing?
Controller:
IActionResult GetDados()
{
var list = _itensService.GetDadosXXX().ToList();
var sourceFiles = _itensService.PrepareData(list);
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
foreach(SourceFile sf in sourceFile)
{
ZipArchiveEntry zipItem = zip.CreateEntry(sf.Name + "." + sd.Extension)
using (MemoryStream fileMemoryStream = new MemoryStream(sf.FileBytes))
{
using (Stream entryStream = zipItem.Open())
{
fileMemoryStream.CopyTo(entryStream);
}
}
}
}
}
return File(FileBytes, "application/zip", ZipArchiveTest.zip");
}
Service:
public IEnumerable<SourceFile> PreparaData(List<XXXData> data)
{
List<SourceFile> result = new List<SourceFile>();
string archiveName = "Test_";
var mStream = new MemoryStream();
int aux = 1;
foreach(object item in data)
{
var binFormatter = new BinaryFormatter();
binFormatter.Serialize(mStream, item);
aux++;
}
result.Add(new SourceFile { Name = archiveName + aux, Extension = "csv", FileBytes = mStream.toArray() });
return result;
}
SourceFile:
public class SourceFile
{
public string Name { get; set; }
public string Extension { get; set; }
public Byte[] FileBytes { get; set; }
}
Let me know if something more is needed...
I need to generate multiple .CSV
files from an object and then zip all the files.
This is what I got, I can't make a way to split the .csv
file in 2 if it's needed, and the .csv
file is broken, I got a lot of text errors in it that wasn't on the list...
What is the best approach to do this? Am I close to the right thing?
Controller:
IActionResult GetDados()
{
var list = _itensService.GetDadosXXX().ToList();
var sourceFiles = _itensService.PrepareData(list);
byte[] bytes = null;
using (MemoryStream ms = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
foreach(SourceFile sf in sourceFile)
{
ZipArchiveEntry zipItem = zip.CreateEntry(sf.Name + "." + sd.Extension)
using (MemoryStream fileMemoryStream = new MemoryStream(sf.FileBytes))
{
using (Stream entryStream = zipItem.Open())
{
fileMemoryStream.CopyTo(entryStream);
}
}
}
}
}
return File(FileBytes, "application/zip", ZipArchiveTest.zip");
}
Service:
public IEnumerable<SourceFile> PreparaData(List<XXXData> data)
{
List<SourceFile> result = new List<SourceFile>();
string archiveName = "Test_";
var mStream = new MemoryStream();
int aux = 1;
foreach(object item in data)
{
var binFormatter = new BinaryFormatter();
binFormatter.Serialize(mStream, item);
aux++;
}
result.Add(new SourceFile { Name = archiveName + aux, Extension = "csv", FileBytes = mStream.toArray() });
return result;
}
SourceFile:
public class SourceFile
{
public string Name { get; set; }
public string Extension { get; set; }
public Byte[] FileBytes { get; set; }
}
Let me know if something more is needed...
Share Improve this question edited Jan 30 at 13:43 Pedro Martins asked Jan 30 at 4:48 Pedro MartinsPedro Martins 11 bronze badge 8 | Show 3 more comments1 Answer
Reset to default 0BinaryFormatter
is obsolete, and should not be used for anything except loading legacy data, and then only with great care due to the security issues that made it obsolete. BinaryFormatter will also use its own internal binary format for objects, hence the name, and this is format has nothing to do whatsoever with comma separated values.
If your object is a simple collection of plain properties you can use CSV helper to help create the csv file. Do not write to an intermediate file, just write to the entry stream directly:
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
...
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
};
...
using (var csv = new CsvWriter(entryStream , CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
If your objects are more complex you should probably consider a serialization format that supports hierarchical objects, like json, xml, protobuf etc.
aux
in your Service? This way all objects'Name
in Controller'ssourceFiles
have the same name. Furthermore,aux
is not declared and yourforeach
definition is missingitem
declaration. – Mike-Kilo Commented Jan 30 at 7:54BinFormatter
? – Klaus Gütter Commented Jan 30 at 11:21BinaryFormatter
, notBinFormatter
. And it is definitely not meant to write text files. And it is also deprecated. – Klaus Gütter Commented Jan 30 at 13:14