Linq to Excel with multiple tabs [duplicate] - c#

This question already has answers here:
How do I create an Excel (.XLS and .XLSX) file in C# without installing Microsoft Office?
(47 answers)
Closed 9 years ago.
I use Entity Framework together with Linq to fill my gridviews.
I would like to get the same data I get from the Linq in an excel.
Also a second tab in the same excel sheet should come from another Linq query.
Whats the easiest and best way to do this?

There are two parts to this. The first is to serialise your linq collection to CSV. You can serialise an enumerable method like this:
public static string ToCsv<T>(string separator, IEnumerable<T> objectlist)
{
Type t = typeof(T);
FieldInfo[] fields = t.GetFields();
string header = String.Join(separator, fields.Select(f => f.Name).ToArray());
StringBuilder csvdata = new StringBuilder();
csvdata.AppendLine(header);
foreach (var o in objectlist)
csvdata.AppendLine(ToCsvFields(separator, fields, o));
return csvdata.ToString();
}
That method won't help you with deep objects but it will get you to CSV. The second stage is to build the XSLX format (assuming that 2 CSVs won't be enough). For that I would recommend the Open XML SDK from Microsoft to build the two worksheets from your CSV string. I also like this answer for building an Excel spreadsheet.

Related

C# equivalent of INPUT # Statement from BASIC/VB? [duplicate]

This question already has answers here:
Reading CSV files using C#
(12 answers)
Closed 5 years ago.
I've got ~500 csv files, without headers, and a legacy BASIC program where the data is imported and saved as variables:
OPEN "filename" FOR INPUT AS #1
INPUT #1, var1, var2, var3$, var4, etc
Most of the files have > 60 fields, and therefore I do not think the answer given here is applicable.
I've so far been unable to find a way to do this in C#.
The new program is a Windows Forms application, and I'm going to have classes for certain objects, and the data in the csv's relate to properties of the objects. I'm going to initialize the object using either a string depicting the file to open, or a dataset if that is the correct way to go about doing this.
Does anyone know of a way to do this in C#, either using 3rd party libraries or not?
I recommend you to use CsvHelper or FileHelpers.
Example with CsvHelper
Create a class with the structure of your CSV
public class Record {
public string Field1 {get;set;}
public int Field2 {get;set;}
public double Field3 {get;set;}
}
Read all records
using (var sr = new StreamReader("yourFile.csv"))
{
var csv = new CsvReader( sr );
var records = csv.GetRecords<Record>().ToList();
}

Populate existing excel template containing columns from a table in SQL Server using C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
My C# project requires excel report generation. I have an existing excel template which contains columns whose values is to be populated from SQL Server table and certain fields(e.g TestCasePassed, TestCaseFailed etc.)in that excel template which is to be populated with values from code.
i.e. Excel template format
TestCasePassed: TestCaseFailed:
Date:
Name Designation Salary TestStatus
I require the C# code for this process. Thanks in advance.
I am actually new to C# and I don't have much idea about how to proceed but yes I have to do it using Microsoft.Interop.
There has to be 100s of way of doing this and, without you being more specific, the question may be more opinion based than anythign else.
If I had this task (and assuming there are a reasonably small number of records) with an existing db I'd just do
Entity Framework db first to the existing sql database
Get the entries from the DB
Write to the spreadsheet using EPPlus
I therefore might end up with code something like this:
List<Entry> FromDb()
{
List<Entry> res;
using (var dbContext = new MyEntities()
{
res = dbContext.Where(e=>MeetsMyFilterCriteria(e)).ToList()
}
return res;
}
Main()
{
FileInfo fileInfo = new FileInfo("path/to/excelTemplateFile.xlsx");
using (var excelPackage = new ExcelPackage(fileInfo))
{
ExcelWorksheet sheet = excelPackage.Workbook.Worksheets["MyWorksheenName"];
BaseRange startRange = sheet.Range["A2"] //or wherever data is to go
int offset=0;
foreach (entry in FromDb())
{
startRange.Offset(offset,0).Value = entry.PropertyA;
startRange.Offset(offset,1).Value = entry.PropertyB;
startRange.Offset(offset,2).Value = entry.PropertyC;
// and so on ...
offset++;
}
excelPackage.SaveAs("path/to/excelOutput.xls");
}
}
This approach is nice and easy to implement but would not scale nicely to 1000s of exports of hundreds of thousands of rows but provided we are talking small numbers of rows and relativaly few export the poor performance is negligible and offset by the ease of implementation.
You can use EasyXLS Excel library. Create a query from SQL Server table and populate a DataSet. Load the existing Excel template and insert the DataSet into the sheet.
//Load Excel template
ExcelDocument template = new ExcelDocument();
template.easy_LoadXLSXFile("template.xlsx");//or easyLoadXLSFile for xls file (xltx/xlt)
//Get the sheet from the Excel file
ExcelWorksheet sheet = (ExcelWorksheet)template.easy_getSheetAt(0);
//Populate the sheet with SQL table values
sheet.easy_insertDataset(dataSet, false);
For more details about how to populate the DataSet or how to format the cells, take a look on more code samples about how to export DataSet to Excel.

Store String Array with Values in Application Settings [duplicate]

This question already has answers here:
How to save a List<string> on Settings.Default?
(4 answers)
Closed 6 years ago.
I've modified my Settings.settings file in order to have system_Filters be a System.String[].
I would like to populate this variable within the Visual Studio designer and not from within the code. I can get it to work within the code using the following:
Properties.Settings.Default.system_Filters = new string[] { "a", "b", "c" };
string _systemFilters = Properties.Settings.Default.system_Filters;
This works correctly. However, I don't have a nice place to put this in my code and ideally want to type it in the Settings.setting file. This value will not be modified. I've tried almost every variant I can think of, but the result is always the same.
Does anyone know the correct syntax? I'm also open to using a StringCollection if that's easier.
Try to use StringCollection instead of string[]. It is natively supported by the settings designer.
The value is stored as XML, but you don't need to edit it manually. When you select StringCollection in the Type column, the editor in the Value column changes; there is a ... button, which opens a dialog to type the strings.

XML from DataTable using Linq

This code
XmlDataDocument xmlDataDocument = new XmlDataDocument(ds);
does not work for me, because the node names are derived from the columns' encoded ColumnName property and will look like "last_x20_name", for instance. This I cannot use in the resulting Excel spreadsheet. In order to treat the column names to make them something more friendly, I need to generate the XML myself.
I like LINQ to XML, and one of the responses to this question contained the following snippets:
XDocument doc = new XDocument(new XDeclaration("1.0","UTF-8","yes"),
new XElement("products", from p in collection
select new XElement("product",
new XAttribute("guid", p.ProductId),
new XAttribute("title", p.Title),
new XAttribute("version", p.Version))));
The entire goal is to dynamically derive the column names from the dataset, so hardcoding them is not an option. Can this be done with Linq and without making the code much longer?
It ought to be possible.
In order to use your Dataset as a source you need Linq-to-Dataset.
Then you would need a nested query
// untested
var data = new XElement("products",
from row in ds.Table["ProductsTable"].Rows.AsEnumerable()
select new XElement("product",
from column in ds.Table["ProductsTable"].Columns // not sure about this
select new XElement(colum.Fieldname, rows[colum.Fieldname])
) );
I appreciate the answers, but I had to abandon this approach altogether. I did manage to produce the XML that I wanted (albeit not with Linq), but of course there is a reason why the default implementation of the XmlDataDocument constructor uses the EncodedColumnName - namely that special characters are not allowed in element names in XML. But since I wanted to use the XML to convert what used to be a simple CSV file to the XML Spreadsheet format using XSLT (customer complains about losing leading 0's in ZIP codes etc when loading the original CSV into Excel), I had to look into ways that preserve the data in Excel.
But the ultimate goal of this is to produce a CSV file for upload to the payroll processor, and they mandate the column names to be something that is not XML-compliant (e.g. "File #"). The data is reviewed by humans before the upload, and they use Excel.
I resorted to hard-coding the column names in the XSLT after all.

Writing a collection to Excel

I'm working in VS2005 and I need the C# syntax write to write collection values in an Excel sheet. I initialize the collection like this:
Reports oReports =new Reports();//oReports is a collection
Assuming that this collection has values, how would I write them to Excel?
You could do something quick and dirty if you don't want to faff around learning how to write to Excel - just write out to a .csv file, open it yourself in excel and save as Excel format.
Just output in a stream, such as: (will work if your report values have commas in them too)
using (StreamWriter sw = new StreamWriter(#"C:\file.csv"))
{
StringBuilder csvLine = new StringBuilder();
//Enter your header row here:
csvLine.Append("Header1,Header2,Header3");
sw.WriteLine(csvLine.ToString());
foreach (Report report in Reports)
{
csvLine = new StringBuilder();
csvLine.Append(string.Format("\"{0}\",", report.Value1));
csvLine.Append(string.Format("\"{0}\",", report.Value2));
csvLine.Append(string.Format("\"{0}\"", report.Value3)); //etc
sw.WriteLine(csvLine.ToString());
}
sw.Flush();
}
Loop through the collection and add the collection values to cells in your spreadsheet.
Here's a couple links on how to work with an excel spreadsheet in .Net
http://www.c-sharpcorner.com/UploadFile/thiagu304/ExcelAutomation01052007080910AM/ExcelAutomation.aspx
http://support.microsoft.com/default.aspx?scid=kb;EN-US;302084
Convert your reports to an object array (two dimensional), and assign the array to an excel range

Categories