CsvHelper How can I save several classes in the same file - c#

How can I save several classes in the same file with CsvHelper? For example, through the different sheets. I tried like this but unfortunately it does not work.
using (var writer = new CsvWriter(new StreamWriter(#"db.csv")))
{
writer.WriteRecords(this.Class1List);
writer.WriteRecords(this.Class2List);
}

try
using (var writer = new CsvWriter(new StreamWriter(#"db.csv", true)))
{
writer.WriteRecords(this.Class1List);
writer.WriteRecords(this.Class2List);
}

Related

C# How to delete certain rows from a CSV file and save it as a new CSV using CsvHelper?

I'm trying to delete certain rows from my CSV file but since I'm new to C# I can't figure out how to do it right.
I have this code that loads a CSV file and goes trough it.
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Books>();
var books = records.ToImmutableArray();
for (int i = 0; i < books.Length; ++i)
{
if (books[i].title == "someTitle")
{
//Delete this row
}
}
//Overwrite old csv
}
But I cannot find the code that would delete the indicated row.
Any help is appreciated.
You could pull all off the records into memory and then write them back to the file.
List<Books> records;
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
records = csv.GetRecords<Books>().ToList();
for (int i = 0; i < records.Count; ++i)
{
if (records[i].Title == "someTitle")
{
records.RemoveAt(i);
}
}
}
using (var writer = new StreamWriter(#"Data\myCSV.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.WriteRecords(records);
}
For a larger file you might want to read one record at a time to memory and write it immediately back to a temporary file. Then delete the original file and rename the temporary file.
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
using (var writer = new StreamWriter(#"Data\myCSV_Temp.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
Books record;
csv.Read();
csv.ReadHeader();
csvWriter.WriteHeader(typeof(Books));
while (csv.Read())
{
record = csv.GetRecord<Books>();
if (record.Title != "someTitle")
{
csvWriter.NextRecord();
csvWriter.WriteRecord(record);
}
}
}
File.Delete(#"Data\myCSV.csv");
File.Move(#"Data\myCSV_Temp.csv", #"Data\myCSV.csv");
From https://github.com/JoshClose/CsvHelper/issues/1397:
CsvHelper is forward only, so you'll need to read through the existing file and write a new one.
There are too many ways of doing this not specifically using CsvHelper, hence i'm listing few suggestions you can try
Simplest solution without getting into details, if the file is small enough(in MBs), read all lines into a List or IEnumerable and then you can do any operation on that collection and write the collection back to the file.
if you are new to c# try out all basic file operations before working on the actual project . Follow a tutorial such as https://www.tutorialspoint.com/csharp/csharp_file_io.htm or videos on youtube
Text Files : https://www.youtube.com/watch?v=cST5TT3OFyg
File IO : https://www.youtube.com/watch?v=9mUuJIKq40M
Use free tools like LinqPad or dotnetfiddle to try small code snippets before writing a large program.
once you are comfortable working with files using .Net libraries, you can look at using libraries such as https://www.filehelpers.net/ which make it very easy to work with files with a lot of configurable options. They also have a lot of turials on their website to work with files.

How do I append CSV using CSV helper?

I went through documentation and I didn't see anything for it. I'm using the same exact write function from documentation but the problem is I also need to append. So far I've tried reading it than adding the CSV into a list than I write the list to CSV. Is there a better way I could append?
The exact write function I use with my own variables
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
};
using (var writer = new StreamWriter("path\\to\\file.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
What I use to read but with my own variables:
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Foo>();
}
Hopefully someone can help!
Use the StreamWriter(String, Boolean) constructor to specify you want to append to an existing file:
Initializes a new instance of the StreamWriter class for the specified file by using the default encoding and buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.
Parameters
path
String
The complete file path to write to.
append
Boolean
true to append data to the file; false to overwrite the file. If the specified file does not exist, this parameter has no effect, and the constructor creates a new file.
As for your CsvHelper CsvWriter, you need to configure it to omit the header depending on if you are appending or creating:
bool append = true;
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.HasHeaderRecord = !append;
using (var writer = new StreamWriter("path\\to\\file.csv", append))
{
using (var csv = new CsvWriter(writer, config))
{
csv.WriteRecords(records);
}
}

Write to a File using CsvHelper in C#

I tried to write to CSV file using CsvHelper in C#.
This is the link to the library http://joshclose.github.io/CsvHelper/
I used the code in web site.
Here is my code:
var csv = new CsvWriter(writer);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in valuess)
{
csv.WriteRecord(value);
}
It writes only a part of data to csv file.
Last rows were missing.
Could you please help with this.
You need to flush the stream. The Using statement will flush when out of scope.
using (TextWriter writer = new StreamWriter(#"C:\test.csv", false, System.Text.Encoding.UTF8))
{
var csv = new CsvWriter(writer);
csv.WriteRecords(values); // where values implements IEnumerable
}
when, I added this code after the loop code is working well
var csv = new CsvWriter(writer);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in valuess)
{
csv.WriteRecord(value);
}
writer.Close();
The problem occurred because I did not close the Connection
Assuming that writer is some kind of TextWriter, you should add a call to flush the contents before closing the writer:
writer.Flush()
If the last lines are missing, this is the most likely reason.
Adding to #greg's answer:
using (var sr = new StreamWriter(#"C:\out.csv", false, Encoding.UTF8)) {
using (var csv = new CsvWriter(sr)) {
csv.WriteRecords(values);
}
}

Trying To Extract Embedded File Attachments From Existing PDF Using C# .NET And PDFBox 1.7.0

I am trying to extract embedded file attachments from an existing PDF using C# .NET and PDFBox.
The following is my code:
using System.Collections.Generic;
using System.IO;
using java.util; // IKVM Java for Microsoft .NET http://www.ikvm.net
using java.io; // IKVM Java for Microsoft .NET http://www.ikvm.net
using org.apache.pdfbox.pdmodel; // PDFBox 1.7.0 http://pdfbox.apache.org
using org.apache.pdfbox.pdmodel.common; // PDFBox 1.7.0 http://pdfbox.apache.org
using org.apache.pdfbox.pdmodel.common.filespecification; // PDFBox 1.7.0 http://pdfbox.apache.org
using org.apache.pdfbox.cos; // PDFBox 1.7.0 http://pdfbox.apache.org
namespace PDFClass
{
public class Class1
{
public Class1 ()
{
}
public void ReadPDFAttachments (string existingFileNameFullPath)
{
PDEmbeddedFilesNameTreeNode efTree;
PDComplexFileSpecification fs;
FileStream stream;
ByteArrayInputStream fakeFile;
PDDocument pdfDocument = new PDDocument();
PDEmbeddedFile ef;
PDDocumentNameDictionary names;
Map efMap = new HashMap();
pdfDocument = PDDocument.load(existingFileNameFullPath);
PDDocumentNameDictionary namesDictionary = new PDDocumentNameDictionary(pdfDocument.getDocumentCatalog());
PDEmbeddedFilesNameTreeNode embeddedFiles = namesDictionary.getEmbeddedFiles(); // some bug is currently preventing this call from working! >:[
if (embeddedFiles != null)
{
var aKids = embeddedFiles.getKids().toArray();
List<PDNameTreeNode> kids = new List<PDNameTreeNode>();
foreach (object oKid in aKids)
{
kids.Add(oKid as PDNameTreeNode);
}
if (kids != null)
{
foreach (PDNameTreeNode kid in kids)
{
PDComplexFileSpecification spec = (PDComplexFileSpecification)kid.getValue("ZUGFERD_XML_FILENAME");
PDEmbeddedFile file = spec.getEmbeddedFile();
fs = new PDComplexFileSpecification();
// Loop through each file for re-embedding
byte[] data = file.getByteArray();
int read = data.Length;
fakeFile = new ByteArrayInputStream(data);
ef = new PDEmbeddedFile(pdfDocument, fakeFile);
fs.setEmbeddedFile(ef);
efMap.put(kid.toString(), fs);
embeddedFiles.setNames(efMap);
names = new PDDocumentNameDictionary(pdfDocument.getDocumentCatalog());
((COSDictionary)efTree.getCOSObject()).removeItem(COSName.LIMITS); // Bug in PDFBox code requires we do this, or attachment will not embed. >:[
names.setEmbeddedFiles(embeddedFiles);
pdfDocument.getDocumentCatalog().setNames(names);
fs.getCOSDictionary().setString("Desc", kid.toString()); // adds a description to attachment in PDF attachment list
}
}
}
}
}
}
The variable embeddedFiles is always null. even though I put a break in the code and can see the PDF file clearly has the attachment in it.
Any assistance would be greatly appreciated!

Overwriting Writer Issue

I'm writing a list to a file, the list gets data from the form app from text I type in. This works but it overwrites the file every time I start the form instead of saving it and adding new data. How Can I add "AppendAllLines" or "WriteAllLines" to this as a solution?
public List<String> listDeliveries()
{
List<String> listDeliveries = new List<string>();
using (StreamWriter writer = new StreamWriter("Database.txt"))
{
foreach (Delivery del in deliveries)
{
String delAsString = del.summary();
listDeliveries.Add(delAsString);
writer.WriteLine(delAsString);
}
}
return listDeliveries;
}
var listDeliveries = deliveries.Select(d=>d.summary()).ToList();
File.AppendAllLines("Database.txt", listDeliveries);
return listDeliveries;
You can use ToList to create your list and File.AppendAllLines to append the lines from the list:
List<string> listDeliveries = deliveries.Select(d => d.summary())
.ToList();
File.AppendAllLines("Database.txt", listDeliveries);
How Can I add "AppendAllLines" or "WriteAllLines" to this as a solution?
Well it looks like you just want:
List<String> listDeliveries = deliveries.Select(x => x.summary()).ToList();
File.AppendAllLines("Database.txt", listDeliveries);
return listDeliveries;
(Yes, you can create the StreamWriter with true as the second argument, but AppendAllLines is simpler...)
You can use
using (StreamWriter writer = new StreamWriter("Database.txt", true))
To append rather than overwrite
Use overloaded constructor that allows you to specify whether to append or not. The default is false
StreamWriter writer = new StreamWriter("Database.txt", true)
When you create the StreamWriter, pass in a boolean that will tell it to append data to the file instead of overwrite.
using (StreamWriter writer = new StreamWriter("Database.txt", true))

Categories