How convert a csv into .xlsx file? - c#

I'm a french student in engineering school.
I have a work to do in my company (yes I work too).
I already developped an application that take xlsx file in input, I use NPOI library.
But now I need to take csv in input file, I tried several things without success.
I just need to convert a csv file as XSSFworkbook and sheet.
I'm newbie but I really want to improve my competences with c#.
Thanks for your help.

I've found on Github a sample that could help you:
class Program
{
static void Main(string[] args)
{
string csvDocument = #"FL_insurance_sample.csv";
var lines = ReadCsv(csvDocument, delimiter: ',');
ConvertWithNPOI("NPOI.xlsx", "NPOI", lines);
}
private static bool ConvertWithNPOI(string excelFileName, string worksheetName, IEnumerable<string[]> csvLines)
{
if (csvLines == null || csvLines.Count() == 0)
{
return (false);
}
int rowCount = 0;
int colCount = 0;
IWorkbook workbook = new XSSFWorkbook();
ISheet worksheet = workbook.CreateSheet(worksheetName);
foreach (var line in csvLines)
{
IRow row = worksheet.CreateRow(rowCount);
colCount = 0;
foreach (var col in line)
{
row.CreateCell(colCount).SetCellValue(TypeConverter.TryConvert(col));
colCount++;
}
rowCount++;
}
using (FileStream fileWriter = File.Create(excelFileName))
{
workbook.Write(fileWriter);
fileWriter.Close();
}
worksheet = null;
workbook = null;
return true;
}
private static bool ConvertWithEPPlus(string csvFileName, string excelFileName, string worksheetName, char delimiter = ';')
{
bool firstRowIsHeader = false;
var format = new ExcelTextFormat();
format.Delimiter = delimiter;
format.EOL = "\r"; // DEFAULT IS "\r\n";
// format.TextQualifier = '"';
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFileName)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetName);
worksheet.Cells["A1"].LoadFromText(new FileInfo(csvFileName), format, OfficeOpenXml.Table.TableStyles.Medium27, firstRowIsHeader);
package.Save();
}
return (true);
}
private static IEnumerable<string[]> ReadCsv(string fileName, char delimiter = ';')
{
var lines = System.IO.File.ReadAllLines(fileName, Encoding.UTF8).Select(a => a.Split(delimiter));
return (lines);
}
}
original https://github.com/Leftyx/ConvertCsvToExcel/blob/master/ConvertCsvToExcel/Program.cs

Related

Need to convert scientific value to text

I am trying to convert csv to xls in which there is Bank Account No (16 digit) need to convert it to text
I tried with EPPlus package by which xls is getting generated easily but Bank Account column gets converted to scientific value.Also tried to convert column to numeric and text but thats not working
private void csvToXls(string source,string destination,string fileName)
{
string csvFileName = source;
string excelFileName = destination+"/"+fileName+".xls";
string worksheetsName = "sheet 1";
bool firstRowIsHeader = false;
var format = new ExcelTextFormat();
format.Delimiter = '|';
format.EOL = "\n"; // DEFAULT IS "\r\n";
// format.TextQualifier = '"';
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFileName)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName);
worksheet.Cells["A1"].LoadFromText(new FileInfo(csvFileName), format, OfficeOpenXml.Table.TableStyles.None, firstRowIsHeader);
foreach (var cell in worksheet.Cells["C:C"])
{
cell.Value = Convert.ToString(cell.Value);
}
foreach (var cell in worksheet.Cells["AC:AC"])
{
cell.Value = Convert.ToString(cell.Value);
}
worksheet.Cells["C:C"].Style.Numberformat.Format = "#0";
worksheet.Cells["C:C"].Style.Numberformat.Format = "#";
worksheet.Cells["AC:AC"].Style.Numberformat.Format = "#";
package.Save();
}
}
Need to convert columns to text which should not be scientific value.Please suggest
Input : In test.csv below input is there
IMDATA||12345678910124567895274|1|NAME|||||||||TEST|||||||||||TESTING||||3301003726558|TDATASTING|TESTING|27-09-2019
Getting Output :
Expected Output :
You need to provide eDataTypes to LoadFromText method for each column, if no types provide for the column it will set to the General by default
So, provide the `eDataTypes to ExcelTextFormat.
I just added for 3 columns and its worked well.
public static void csvToXls(string source, string destination, string fileName)
{
string csvFileName = source;
string excelFileName = destination + "/" + fileName + ".xls";
string worksheetsName = "sheet 1";
bool firstRowIsHeader = false;
var format = new ExcelTextFormat();
var edataTypes = new eDataTypes[] { eDataTypes.String, eDataTypes.String, eDataTypes.String };
format.DataTypes = edataTypes;
format.Delimiter = '|';
format.EOL = "\n"; // DEFAULT IS "\r\n";
// format.TextQualifier = '"';
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFileName)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName);
worksheet.Cells["A1"].LoadFromText(new FileInfo(csvFileName), format, OfficeOpenXml.Table.TableStyles.None, firstRowIsHeader);
package.Save();
}
}
OR
You can try to read the text manually
public static void csvToXls(string source, string destination, string fileName)
{
string csvFileName = source;
string excelFileName = destination + "/" + fileName + ".xls";
string worksheetsName = "sheet 1";
using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFileName)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName);
var text = File.ReadAllText(source);
var rows = text.Split('\n');
for (int rowIndex = 0; rowIndex < rows.Length; rowIndex++)
{
var excelRow = worksheet.Row(rowIndex+1);
var columns = rows[rowIndex].Split('|');
for (int colIndex = 0; colIndex < columns.Length; colIndex++)
{
worksheet.Cells[rowIndex +1, colIndex +1].Value = columns[colIndex];
}
}
package.Save();
}
}

C# not creating the excel file and cannot write in different excel sheets

First of all in my code im opening an excel sheet and reading it into a list. Second of all im closing this excel sheet and creating a new excel sheet:
excel_init("C:\\Users\\oma\\Desktop\\excel2.xlsx"); // this path does NOT exist yet
Next its going to this method:
static void excel_init(String path)
{
appExcel = new Microsoft.Office.Interop.Excel.ApplicationClass();
if (System.IO.File.Exists(path))
{
// then go and load this into excel
newWorkbook_First = appExcel.Workbooks.Open(path, true, true);
objsheet = (_Worksheet)appExcel.ActiveWorkbook.ActiveSheet;
}
else
{
try
{
appExcel = new Microsoft.Office.Interop.Excel.ApplicationClass();
appExcel.Visible = true;
newWorkbook_First = appExcel.Workbooks.Add(1);
objsheet = (Microsoft.Office.Interop.Excel.Worksheet)newWorkbook_First.Sheets[1];
objsheet.Name = ("test");
var newSheet3 = (Microsoft.Office.Interop.Excel.Worksheet)appExcel.Worksheets.Add(Type.Missing, appExcel.Worksheets[appExcel.Worksheets.Count], 1, XlSheetType.xlWorksheet);
newSheet3.Name = "test2";
var newSheet2 = (Microsoft.Office.Interop.Excel.Worksheet)appExcel.Worksheets.Add(Type.Missing, appExcel.Worksheets[appExcel.Worksheets.Count], 1, XlSheetType.xlWorksheet);
newSheet2.Name = "test3";
}
catch (Exception e)
{
Console.Write("Error");
}
finally
{
}
}
}
It wont create excel2.xlsx on my desktop, why not?
Next in my main I am shouting excel_setValue this way:
excel_setValue("C", "hello", "");
This is the excel_setValue function:
static void excel_setValue(string cellname, string value, string color)
{
objsheet.get_Range(cellname).set_Value(Type.Missing, value);
if (kleur == "red")
{
objsheet.get_Range(cellname).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
}
}
How do I add the sheet to this? For exmaple: excel_setValue(cellname, value, color, sheetname)
Finally I do excel_close();
the excel_close function:
static void excel_close()
{
if (appExcel != null)
{
try
{
newWorkbook_First.Close();
System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel.ActiveWorkbook.ActiveSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel.ActiveWorkbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(appExcel);
appExcel = null;
objsheet = null;
}
catch (Exception ex)
{
appExcel = null;
Console.WriteLine("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
It closes and ask me if I wanna save/not-save or cancel it. And it will save # documents with no errors given
I create my Excel like this worked fine for me!
You need to do the folowing in you code before the newWorkbook_First.close(); part:
newWorkbook_First.SaveAs(totalPath);
I hope this will help you solve the problems..
using Excel = Microsoft.Office.Interop.Excel;
internal static bool ExportDGV(DataGridView DGV, List<string> selectedCustomerList, string path, string fileName, string exportName, int exportType, string mailSubject)
{
string totalPath;
//Create an Excel application instance
Excel.Application excelApp = new Excel.Application();
Excel.Workbook excelWorkBook = excelApp.Application.Workbooks.Add();
Excel._Worksheet worksheet = null;
excelApp.Visible = false;
worksheet = excelWorkBook.ActiveSheet;
//set headers
for (int i = 1; i < DataGridView.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = DGV.Columns[i - 1].HeaderText;
}
createList(worksheet, DGV);
//Create excel with the choosen name
Worksheet sheet1 = excelWorkBook.Worksheets[1];
worksheet.Name = fileName;
totalPath = path + "/" + fileName + ".xlsx";
//if path exist add a number
totalPath = directoryExist(totalPath, path, fileName);
//Save exel and Quit exelApp
excelWorkBook.SaveAs(totalPath);
excelWorkBook.Close();
excelApp.Quit();
}
You can use EpPlus library for excel. It is very easy to use and well documented. You don't need to use COM classes anymore

Optimal way to Read an Excel file (.xls/.xlsx)

I know that there are different ways to read an Excel file:
Iterop
Oledb
Open Xml SDK
Compatibility is not a question because the program will be executed in a controlled environment.
My Requirement :
Read a file to a DataTable / CUstom Entities (I don't know how to make dynamic properties/fields to an object[column names will be variating in an Excel file])
Use DataTable/Custom Entities to perform some operations using its data.
Update DataTable with the results of the operations
Write it back to excel file.
Which would be simpler.
Also if possible advice me on custom Entities (adding properties/fields to an object dynamically)
Take a look at Linq-to-Excel. It's pretty neat.
var book = new LinqToExcel.ExcelQueryFactory(#"File.xlsx");
var query =
from row in book.Worksheet("Stock Entry")
let item = new
{
Code = row["Code"].Cast<string>(),
Supplier = row["Supplier"].Cast<string>(),
Ref = row["Ref"].Cast<string>(),
}
where item.Supplier == "Walmart"
select item;
It also allows for strongly-typed row access too.
I realize this question was asked nearly 7 years ago but it's still a top Google search result for certain keywords regarding importing excel data with C#, so I wanted to provide an alternative based on some recent tech developments.
Importing Excel data has become such a common task to my everyday duties, that I've streamlined the process and documented the method on my blog: best way to read excel file in c#.
I use NPOI because it can read/write Excel files without Microsoft Office installed and it doesn't use COM+ or any interops. That means it can work in the cloud!
But the real magic comes from pairing up with NPOI Mapper from Donny Tian because it allows me to map the Excel columns to properties in my C# classes without writing any code. It's beautiful.
Here is the basic idea:
I create a .net class that matches/maps the Excel columns I'm interested in:
class CustomExcelFormat
{
[Column("District")]
public int District { get; set; }
[Column("DM")]
public string FullName { get; set; }
[Column("Email Address")]
public string EmailAddress { get; set; }
[Column("Username")]
public string Username { get; set; }
public string FirstName
{
get
{
return Username.Split('.')[0];
}
}
public string LastName
{
get
{
return Username.Split('.')[1];
}
}
}
Notice, it allows me to map based on column name if I want to!
Then when I process the excel file all I need to do is something like this:
public void Execute(string localPath, int sheetIndex)
{
IWorkbook workbook;
using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read))
{
workbook = WorkbookFactory.Create(file);
}
var importer = new Mapper(workbook);
var items = importer.Take<CustomExcelFormat>(sheetIndex);
foreach(var item in items)
{
var row = item.Value;
if (string.IsNullOrEmpty(row.EmailAddress))
continue;
UpdateUser(row);
}
DataContext.SaveChanges();
}
Now, admittedly, my code does not modify the Excel file itself. I am instead saving the data to a database using Entity Framework (that's why you see "UpdateUser" and "SaveChanges" in my example). But there is already a good discussion on SO about how to save/modify a file using NPOI.
Using OLE Query, it's quite simple (e.g. sheetName is Sheet1):
DataTable LoadWorksheetInDataTable(string fileName, string sheetName)
{
DataTable sheetData = new DataTable();
using (OleDbConnection conn = this.returnConnection(fileName))
{
conn.Open();
// retrieve the data using data adapter
OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "$]", conn);
sheetAdapter.Fill(sheetData);
conn.Close();
}
return sheetData;
}
private OleDbConnection returnConnection(string fileName)
{
return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
}
For newer Excel versions:
return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=Excel 12.0;");
You can also use Excel Data Reader an open source project on CodePlex. Its works really well to export data from Excel sheets.
The sample code given on the link specified:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Reference: How do I import from Excel to a DataSet using Microsoft.Office.Interop.Excel?
Try to use this free way to this, https://freenetexcel.codeplex.com
Workbook workbook = new Workbook();
workbook.LoadFromFile(#"..\..\parts.xls",ExcelVersion.Version97to2003);
//Initialize worksheet
Worksheet sheet = workbook.Worksheets[0];
DataTable dataTable = sheet.ExportDataTable();
If you can restrict it to just (Open Office XML format) *.xlsx files, then probably the most popular library would be EPPLus.
Bonus is, there are no other dependencies. Just install using nuget:
Install-Package EPPlus
Try to use Aspose.cells library (not free, but trial is enough to read), it is quite good
Install-package Aspose.cells
There is sample code:
using Aspose.Cells;
using System;
namespace ExcelReader
{
class Program
{
static void Main(string[] args)
{
// Replace path for your file
readXLS(#"C:\MyExcelFile.xls"); // or "*.xlsx"
Console.ReadKey();
}
public static void readXLS(string PathToMyExcel)
{
//Open your template file.
Workbook wb = new Workbook(PathToMyExcel);
//Get the first worksheet.
Worksheet worksheet = wb.Worksheets[0];
//Get cells
Cells cells = worksheet.Cells;
// Get row and column count
int rowCount = cells.MaxDataRow;
int columnCount = cells.MaxDataColumn;
// Current cell value
string strCell = "";
Console.WriteLine(String.Format("rowCount={0}, columnCount={1}", rowCount, columnCount));
for (int row = 0; row <= rowCount; row++) // Numeration starts from 0 to MaxDataRow
{
for (int column = 0; column <= columnCount; column++) // Numeration starts from 0 to MaxDataColumn
{
strCell = "";
strCell = Convert.ToString(cells[row, column].Value);
if (String.IsNullOrEmpty(strCell))
{
continue;
}
else
{
// Do your staff here
Console.WriteLine(strCell);
}
}
}
}
}
}
Read from excel, modify and write back
/// <summary>
/// /Reads an excel file and converts it into dataset with each sheet as each table of the dataset
/// </summary>
/// <param name="filename"></param>
/// <param name="headers">If set to true the first row will be considered as headers</param>
/// <returns></returns>
public DataSet Import(string filename, bool headers = true)
{
var _xl = new Excel.Application();
var wb = _xl.Workbooks.Open(filename);
var sheets = wb.Sheets;
DataSet dataSet = null;
if (sheets != null && sheets.Count != 0)
{
dataSet = new DataSet();
foreach (var item in sheets)
{
var sheet = (Excel.Worksheet)item;
DataTable dt = null;
if (sheet != null)
{
dt = new DataTable();
var ColumnCount = ((Excel.Range)sheet.UsedRange.Rows[1, Type.Missing]).Columns.Count;
var rowCount = ((Excel.Range)sheet.UsedRange.Columns[1, Type.Missing]).Rows.Count;
for (int j = 0; j < ColumnCount; j++)
{
var cell = (Excel.Range)sheet.Cells[1, j + 1];
var column = new DataColumn(headers ? cell.Value : string.Empty);
dt.Columns.Add(column);
}
for (int i = 0; i < rowCount; i++)
{
var r = dt.NewRow();
for (int j = 0; j < ColumnCount; j++)
{
var cell = (Excel.Range)sheet.Cells[i + 1 + (headers ? 1 : 0), j + 1];
r[j] = cell.Value;
}
dt.Rows.Add(r);
}
}
dataSet.Tables.Add(dt);
}
}
_xl.Quit();
return dataSet;
}
public string Export(DataTable dt, bool headers = false)
{
var wb = _xl.Workbooks.Add();
var sheet = (Excel.Worksheet)wb.ActiveSheet;
//process columns
for (int i = 0; i < dt.Columns.Count; i++)
{
var col = dt.Columns[i];
//added columns to the top of sheet
var currentCell = (Excel.Range)sheet.Cells[1, i + 1];
currentCell.Value = col.ToString();
currentCell.Font.Bold = true;
//process rows
for (int j = 0; j < dt.Rows.Count; j++)
{
var row = dt.Rows[j];
//added rows to sheet
var cell = (Excel.Range)sheet.Cells[j + 1 + 1, i + 1];
cell.Value = row[i];
}
currentCell.EntireColumn.AutoFit();
}
var fileName="{somepath/somefile.xlsx}";
wb.SaveCopyAs(fileName);
_xl.Quit();
return fileName;
}
I used Office's NuGet Package: DocumentFormat.OpenXml and pieced together the code from that component's doc site.
With the below helper code, was similar in complexity to my other CSV file format parsing in that project...
public static async Task ImportXLSX(Stream stream, string sheetName) {
{
// This was necessary for my Blazor project, which used a BrowserFileStream object
MemoryStream ms = new MemoryStream();
await stream.CopyToAsync(ms);
using (var document = SpreadsheetDocument.Open(ms, false))
{
// Retrieve a reference to the workbook part.
WorkbookPart wbPart = document.WorkbookPart;
// Find the sheet with the supplied name, and then use that
// Sheet object to retrieve a reference to the first worksheet.
Sheet theSheet = wbPart?.Workbook.Descendants<Sheet>().Where(s => s?.Name == sheetName).FirstOrDefault();
// Throw an exception if there is no sheet.
if (theSheet == null)
{
throw new ArgumentException("sheetName");
}
WorksheetPart wsPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));
// For shared strings, look up the value in the
// shared strings table.
var stringTable =
wbPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
// I needed to grab 4 cells from each row
// Starting at row 11, until the cell in column A is blank
int row = 11;
while (true) {
var accountNameCell = GetCell(wsPart, "A" + row.ToString());
var accountName = GetValue(accountNameCell, stringTable);
if (string.IsNullOrEmpty(accountName)) {
break;
}
var investmentNameCell = GetCell(wsPart, "B" + row.ToString());
var investmentName = GetValue(investmentNameCell, stringTable);
var symbolCell = GetCell(wsPart, "D" + row.ToString());
var symbol = GetValue(symbolCell, stringTable);
var marketValue = GetCell(wsPart, "J" + row.ToString()).InnerText;
// DO STUFF with data
row++;
}
}
}
private static string? GetValue(Cell cell, SharedStringTablePart stringTable) {
try {
return stringTable.SharedStringTable.ElementAt(int.Parse(cell.InnerText)).InnerText;
} catch (Exception) {
return null;
}
}
private static Cell GetCell(WorksheetPart wsPart, string cellReference) {
return wsPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference.Value == cellReference)?.FirstOrDefault();
}

NPOI copy range to another worksheet

I am using NPOI to work with Excel in C#. But there is no full documentation how to work with it. I need to copy some range to another worksheet. Does anybody know, how to do this? Maybe you are using another dll(not interop) to provide such functionality. If so, please tell me.
In excel everything is very simple:
Worksheets(2).rows(2).copy newsheet.Range("A1")
Thanks for your answer!
NPOI doesn't support this out of the box but the implementation is straightforward.
Two functions are of interest here: CopyColumn() and CopyRange().
CopyRangeExample() opens a workbook, creates a new output sheet and copies cells (data and style) from one sheet to another.
void CopyRangeExample()
{
var workbook = OpenWorkbook("test.xlsx");
var destinationSheetName = "destination" + (workbook.NumberOfSheets + 1).ToString();
workbook.CreateSheet(destinationSheetName);
ISheet sourceSheet = workbook.GetSheet("source");
ISheet destinationSheet = workbook.GetSheet(destinationSheetName);
CopyColumn("I", sourceSheet, destinationSheet);
CopyRange(CellRangeAddress.ValueOf("C6:E15"), sourceSheet, destinationSheet);
SaveWorkbook(workbook, "test.xlsx");
}
And the rest of the code:
void CopyRange(CellRangeAddress range, ISheet sourceSheet, ISheet destinationSheet)
{
for (var rowNum = range.FirstRow; rowNum <= range.LastRow; rowNum++)
{
IRow sourceRow = sourceSheet.GetRow(rowNum);
if (destinationSheet.GetRow(rowNum)==null)
destinationSheet.CreateRow(rowNum);
if (sourceRow != null)
{
IRow destinationRow = destinationSheet.GetRow(rowNum);
for (var col = range.FirstColumn; col < sourceRow.LastCellNum && col<=range.LastColumn; col++)
{
destinationRow.CreateCell(col);
CopyCell(sourceRow.GetCell(col), destinationRow.GetCell(col));
}
}
}
}
void CopyColumn(string column, ISheet sourceSheet, ISheet destinationSheet)
{
int columnNum = CellReference.ConvertColStringToIndex(column);
var range = new CellRangeAddress(0, sourceSheet.LastRowNum, columnNum, columnNum);
CopyRange(range, sourceSheet, destinationSheet);
}
void CopyCell(ICell source, ICell destination)
{
if (destination != null && source != null)
{
//you can comment these out if you don't want to copy the style ...
destination.CellComment = source.CellComment;
destination.CellStyle = source.CellStyle;
destination.Hyperlink = source.Hyperlink;
switch (source.CellType)
{
case CellType.Formula:
destination.CellFormula = source.CellFormula; break;
case CellType.Numeric:
destination.SetCellValue(source.NumericCellValue); break;
case CellType.String:
destination.SetCellValue(source.StringCellValue); break;
}
}
}
IWorkbook OpenWorkbook(string path)
{
IWorkbook workbook;
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
workbook = WorkbookFactory.Create(fileStream);
}
return workbook;
}
void SaveWorkbook(IWorkbook workbook, string path)
{
using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
{
workbook.Write(fileStream);
}
}
Just remember to include NPOI and System.IO in your project:
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using System.IO;

Export DataTable to Excel File

I have a DataTable with 30+ columns and 6500+ rows.I need to dump the whole DataTable values into an Excel file.Can anyone please help with the C# code.I need each column value to be in a cell.To be precise,I need the exact looking copy of DataTable in an Excel File.Please help.
Thanks,
Vix
use this code...
dt = city.GetAllCity();//your datatable
string attachment = "attachment; filename=city.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in dt.Columns)
{
Response.Write(tab + dc.ColumnName);
tab = "\t";
}
Response.Write("\n");
int i;
foreach (DataRow dr in dt.Rows)
{
tab = "";
for (i = 0; i < dt.Columns.Count; i++)
{
Response.Write(tab + dr[i].ToString());
tab = "\t";
}
Response.Write("\n");
}
Response.End();
This snippet could be faster to implement:
// Example data
DataTable table = new DataTable();
table.Columns.AddRange(new[]{ new DataColumn("Key"), new DataColumn("Value") });
foreach (string name in Request.ServerVariables)
table.Rows.Add(name, Request.ServerVariables[name]);
// This actually makes your HTML output to be downloaded as .xls file
Response.Clear();
Response.ClearContent();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=ExcelFile.xls");
// Create a dynamic control, populate and render it
GridView excel = new GridView();
excel.DataSource = table;
excel.DataBind();
excel.RenderControl(new HtmlTextWriter(Response.Output));
Response.Flush();
Response.End();
Below link is used to export datatable to excel in C# Code.
http://royalarun.blogspot.in/2012/01/export-datatable-to-excel-in-c-windows.html
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
namespace ExportExcel
{
public partial class ExportDatatabletoExcel : Form
{
public ExportDatatabletoExcel()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
//Add Datacolumn
DataColumn workCol = dt.Columns.Add("FirstName", typeof(String));
dt.Columns.Add("LastName", typeof(String));
dt.Columns.Add("Blog", typeof(String));
dt.Columns.Add("City", typeof(String));
dt.Columns.Add("Country", typeof(String));
//Add in the datarow
DataRow newRow = dt.NewRow();
newRow["firstname"] = "Arun";
newRow["lastname"] = "Prakash";
newRow["Blog"] = "http://royalarun.blogspot.com/";
newRow["city"] = "Coimbatore";
newRow["country"] = "India";
dt.Rows.Add(newRow);
//open file
StreamWriter wr = new StreamWriter(#"D:\\Book1.xls");
try
{
for (int i = 0; i < dt.Columns.Count; i++)
{
wr.Write(dt.Columns[i].ToString().ToUpper() + "\t");
}
wr.WriteLine();
//write rows to excel file
for (int i = 0; i < (dt.Rows.Count); i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
if (dt.Rows[i][j] != null)
{
wr.Write(Convert.ToString(dt.Rows[i][j]) + "\t");
}
else
{
wr.Write("\t");
}
}
//go to next line
wr.WriteLine();
}
//close file
wr.Close();
}
catch (Exception ex)
{
throw ex;
}
}
}
}
The most rank answer in this post work, however its is CSV file. It is not actual Excel file. Therefore, you will get a warning when you are opening a file.
The best solution I found on the web is using CloseXML
https://github.com/closedxml/closedxml
You need to Open XML as well.
dt = city.GetAllCity();//your datatable
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt);
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=GridView.xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
Credit: http://www.aspsnippets.com/Articles/Solution-ASPNet-GridView-Export-to-Excel-The-file-you-are-trying-to-open-is-in-a-different-format-than-specified-by-the-file-extension.aspx
I use This in page.`
public void DTToExcel(DataTable dt)
{
// dosya isimleri ileride aynı anda birden fazla kullanıcı aynı dosya üzerinde işlem yapmak ister düşüncesiyle guid yapıldı.
string FileName = Guid.NewGuid().ToString();
FileInfo f = new FileInfo(Server.MapPath("Downloads") + string.Format("\\{0}.xlsx", FileName));
if (f.Exists)
f.Delete(); // delete the file if it already exist.
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearHeaders();
response.ClearContent();
response.Charset = Encoding.UTF8.WebName;
response.AddHeader("content-disposition", "attachment; filename=" + FileName + ".xls");
response.AddHeader("Content-Type", "application/Excel");
response.ContentType = "application/vnd.xlsx";
//response.AddHeader("Content-Length", file.Length.ToString());
// create a string writer
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw)) //datatable'a aldığımız sorguyu bir datagrid'e atayıp html'e çevir.
{
// instantiate a datagrid
DataGrid dg = new DataGrid();
dg.DataSource = dt;
dg.DataBind();
dg.RenderControl(htw);
response.Write(sw.ToString());
dg.Dispose();
dt.Dispose();
response.End();
}
}
}
var lines = new List<string>();
string[] columnNames = dt.Columns.Cast<DataColumn>().
Select(column => column.ColumnName).
ToArray();
var header = string.Join(",", columnNames);
lines.Add(header);
var valueLines = dt.AsEnumerable()
.Select(row => string.Join(",", row.ItemArray));
lines.AddRange(valueLines);
File.WriteAllLines("excel.csv", lines);
Here dt refers to your DataTable pass as a paramter
While not a .NET implementation, you may find that the plug-in TableTools may be highly effective depending on your audience. It relies upon flash which shouldn't be a problem for most cases of needing to actually work in-depth and then want to record tabular information.
The latest version appears to support copying to clipboard, into a CSV, ".XLS" (really just a tab-delimited file named .xls), to a PDF, or create a printer friendly page version with all rows displayed and the rest of your page's contents hidden.
I found the extension on the DataTables site here: http://datatables.net/extras/tabletools/
The download is available in the plug-ins (extras) page here: http://datatables.net/extras/
It supposedly is downloaded as a part of DataTables (hence the phrase "Extras included in the DataTables package") but I didn't find it in the download I have been using. Seems to work wonderfully!
Most answers are actually producing the CSV which I don't always have good experience with, when opening in Excel.
One way of doing it would be also with ACE OLEDB Provider (see also connection strings for Excel). Of course you'd have to have the provider installed and registered. You do have it, if you have Excel installed, but this is something you have to consider when deploying (e.g. on web server).
In below helper class code you'd have to call something like ExportHelper.CreateXlsFromDataTable(dataset.Tables[0], #"C:\tmp\export.xls");
public class ExportHelper
{
private const string ExcelOleDbConnectionStringTemplate = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES\";";
/// <summary>
/// Creates the Excel file from items in DataTable and writes them to specified output file.
/// </summary>
public static void CreateXlsFromDataTable(DataTable dataTable, string fullFilePath)
{
string createTableWithHeaderScript = GenerateCreateTableCommand(dataTable);
using (var conn = new OleDbConnection(String.Format(ExcelOleDbConnectionStringTemplate, fullFilePath)))
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
OleDbCommand cmd = new OleDbCommand(createTableWithHeaderScript, conn);
cmd.ExecuteNonQuery();
foreach (DataRow dataExportRow in dataTable.Rows)
{
AddNewRow(conn, dataExportRow);
}
}
}
private static void AddNewRow(OleDbConnection conn, DataRow dataRow)
{
string insertCmd = GenerateInsertRowCommand(dataRow);
using (OleDbCommand cmd = new OleDbCommand(insertCmd, conn))
{
AddParametersWithValue(cmd, dataRow);
cmd.ExecuteNonQuery();
}
}
/// <summary>
/// Generates the insert row command.
/// </summary>
private static string GenerateInsertRowCommand(DataRow dataRow)
{
var stringBuilder = new StringBuilder();
var columns = dataRow.Table.Columns.Cast<DataColumn>().ToList();
var columnNamesCommaSeparated = string.Join(",", columns.Select(x => x.Caption));
var questionmarkCommaSeparated = string.Join(",", columns.Select(x => "?"));
stringBuilder.AppendFormat("INSERT INTO [{0}] (", dataRow.Table.TableName);
stringBuilder.Append(columnNamesCommaSeparated);
stringBuilder.Append(") VALUES(");
stringBuilder.Append(questionmarkCommaSeparated);
stringBuilder.Append(")");
return stringBuilder.ToString();
}
/// <summary>
/// Adds the parameters with value.
/// </summary>
private static void AddParametersWithValue(OleDbCommand cmd, DataRow dataRow)
{
var paramNumber = 1;
for (int i = 0; i <= dataRow.Table.Columns.Count - 1; i++)
{
if (!ReferenceEquals(dataRow.Table.Columns[i].DataType, typeof(int)) && !ReferenceEquals(dataRow.Table.Columns[i].DataType, typeof(decimal)))
{
cmd.Parameters.AddWithValue("#p" + paramNumber, dataRow[i].ToString().Replace("'", "''"));
}
else
{
object value = GetParameterValue(dataRow[i]);
OleDbParameter parameter = cmd.Parameters.AddWithValue("#p" + paramNumber, value);
if (value is decimal)
{
parameter.OleDbType = OleDbType.Currency;
}
}
paramNumber = paramNumber + 1;
}
}
/// <summary>
/// Gets the formatted value for the OleDbParameter.
/// </summary>
private static object GetParameterValue(object value)
{
if (value is string)
{
return value.ToString().Replace("'", "''");
}
return value;
}
private static string GenerateCreateTableCommand(DataTable tableDefination)
{
StringBuilder stringBuilder = new StringBuilder();
bool firstcol = true;
stringBuilder.AppendFormat("CREATE TABLE [{0}] (", tableDefination.TableName);
foreach (DataColumn tableColumn in tableDefination.Columns)
{
if (!firstcol)
{
stringBuilder.Append(", ");
}
firstcol = false;
string columnDataType = "CHAR(255)";
switch (tableColumn.DataType.Name)
{
case "String":
columnDataType = "CHAR(255)";
break;
case "Int32":
columnDataType = "INTEGER";
break;
case "Decimal":
// Use currency instead of decimal because of bug described at
// http://social.msdn.microsoft.com/Forums/vstudio/en-US/5d6248a5-ef00-4f46-be9d-853207656bcc/localization-trouble-with-oledbparameter-and-decimal?forum=csharpgeneral
columnDataType = "CURRENCY";
break;
}
stringBuilder.AppendFormat("{0} {1}", tableColumn.ColumnName, columnDataType);
}
stringBuilder.Append(")");
return stringBuilder.ToString();
}
}
Working code for Excel Export
try
{
DataTable dt = DS.Tables[0];
string attachment = "attachment; filename=log.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = "";
foreach (DataColumn dc in dt.Columns)
{
Response.Write(tab + dc.ColumnName);
tab = "\t";
}
Response.Write("\n");
int i;
foreach (DataRow dr in dt.Rows)
{
tab = "";
for (i = 0; i < dt.Columns.Count; i++)
{
Response.Write(tab + dr[i].ToString());
tab = "\t";
}
Response.Write("\n");
}
Response.End();
}
catch (Exception Ex)
{ }
Try this to export the data to Excel file same as in DataTable and could customize also.
dtDataTable1 = ds.Tables[0];
try
{
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
Workbook xlWorkBook = ExcelApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
for (int i = 1; i > 0; i--)
{
Sheets xlSheets = null;
Worksheet xlWorksheet = null;
//Create Excel sheet
xlSheets = ExcelApp.Sheets;
xlWorksheet = (Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
xlWorksheet.Name = "MY FIRST EXCEL FILE";
for (int j = 1; j < dtDataTable1.Columns.Count + 1; j++)
{
ExcelApp.Cells[i, j] = dtDataTable1.Columns[j - 1].ColumnName;
ExcelApp.Cells[1, j].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Green);
ExcelApp.Cells[i, j].Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.WhiteSmoke);
}
// for the data of the excel
for (int k = 0; k < dtDataTable1.Rows.Count; k++)
{
for (int l = 0; l < dtDataTable1.Columns.Count; l++)
{
ExcelApp.Cells[k + 2, l + 1] = dtDataTable1.Rows[k].ItemArray[l].ToString();
}
}
ExcelApp.Columns.AutoFit();
}
((Worksheet)ExcelApp.ActiveWorkbook.Sheets[ExcelApp.ActiveWorkbook.Sheets.Count]).Delete();
ExcelApp.Visible = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
If you to export datatable to excel with formatted header text try like this.
public void ExportFullDetails()
{
Int16 id = Convert.ToInt16(Session["id"]);
DataTable registeredpeople = new DataTable();
registeredpeople = this.dataAccess.ExportDetails(eventid);
string attachment = "attachment; filename=Details.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = "";
registeredpeople.Columns["Reg_id"].ColumnName = "Reg. ID";
registeredpeople.Columns["Name"].ColumnName = "Name";
registeredpeople.Columns["Reg_country"].ColumnName = "Country";
registeredpeople.Columns["Reg_city"].ColumnName = "City";
registeredpeople.Columns["Reg_email"].ColumnName = "Email";
registeredpeople.Columns["Reg_business_phone"].ColumnName = "Business Phone";
registeredpeople.Columns["Reg_mobile"].ColumnName = "Mobile";
registeredpeople.Columns["PositionRole"].ColumnName = "Position";
registeredpeople.Columns["Reg_work_type"].ColumnName = "Work Type";
foreach (DataColumn dc in registeredpeople.Columns)
{
Response.Write(tab + dc.ColumnName);
tab = "\t";
}
Response.Write("\n");
int i;
foreach (DataRow dr in registeredpeople.Rows)
{
tab = "";
for (i = 0; i < registeredpeople.Columns.Count; i++)
{
Response.Write(tab + dr[i].ToString());
tab = "\t";
}
Response.Write("\n");
}
Response.End();
}
I have done the DataTable to Excel conversion with the following code. Hope it's very easy no need to change more just copy & pest the code replace your variable with your variable, and it will work properly.
First create a folder in your solution Document, and create an Excel file MyTemplate.xlsx. you can change those name according to your requirement. But remember for that you have to change the name in code also.
Please find the following code...
protected void GetExcel_Click(object sender, EventArgs e)
{
ManageTicketBS objManageTicket = new ManageTicketBS();
DataTable DT = objManageTicket.GetAlldataByDate(); //this function will bring the data in DataTable format, you can use your function instate of that.
string DownloadFileName;
string FolderPath;
string FileName = "MyTemplate.xlsx";
DownloadFileName = Path.GetFileNameWithoutExtension(FileName) + new Random().Next(10000, 99999) + Path.GetExtension(FileName);
FolderPath = ".\\" + DownloadFileName;
GetParents(Server.MapPath("~/Document/" + FileName), Server.MapPath("~/Document/" + DownloadFileName), DT);
string path = Server.MapPath("~/Document/" + FolderPath);
FileInfo file = new FileInfo(path);
if (file.Exists)
{
try
{
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = true;
response.ContentType = MimeType(Path.GetExtension(FolderPath));
response.AddHeader("Content-Disposition", "attachment;filename=" + DownloadFileName);
byte[] data = File.ReadAllBytes(path);
response.BinaryWrite(data);
HttpContext.Current.ApplicationInstance.CompleteRequest();
response.End();
}
catch (Exception ex)
{
ex.ToString();
}
finally
{
DeleteOrganisationtoSupplierTemplate(path);
}
}
}
public string GetParents(string FilePath, string TempFilePath, DataTable DTTBL)
{
File.Copy(Path.Combine(FilePath), Path.Combine(TempFilePath), true);
FileInfo file = new FileInfo(TempFilePath);
try
{
DatatableToExcel(DTTBL, TempFilePath, 0);
return TempFilePath;
}
catch (Exception ex)
{
return "";
}
}
public static string MimeType(string Extension)
{
string mime = "application/octetstream";
if (string.IsNullOrEmpty(Extension))
return mime;
string ext = Extension.ToLower();
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (rk != null && rk.GetValue("Content Type") != null)
mime = rk.GetValue("Content Type").ToString();
return mime;
}
static bool DeleteOrganisationtoSupplierTemplate(string filePath)
{
try
{
File.Delete(filePath);
return true;
}
catch (IOException)
{
return false;
}
}
public void DatatableToExcel(DataTable dtable, string pFilePath, int excelSheetIndex=1)
{
try
{
if (dtable != null && dtable.Rows.Count > 0)
{
IWorkbook workbook = null;
ISheet worksheet = null;
using (FileStream stream = new FileStream(pFilePath, FileMode.Open, FileAccess.ReadWrite))
{
workbook = WorkbookFactory.Create(stream);
worksheet = workbook.GetSheetAt(excelSheetIndex);
int iRow = 1;
foreach (DataRow row in dtable.Rows)
{
IRow file = worksheet.CreateRow(iRow);
int iCol = 0;
foreach (DataColumn column in dtable.Columns)
{
ICell cell = null;
object cellValue = row[iCol];
switch (column.DataType.ToString())
{
case "System.Boolean":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.Boolean);
if (Convert.ToBoolean(cellValue)) { cell.SetCellFormula("TRUE()"); }
else { cell.SetCellFormula("FALSE()"); }
//cell.CellStyle = _boolCellStyle;
}
break;
case "System.String":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.String);
cell.SetCellValue(Convert.ToString(cellValue));
}
break;
case "System.Int32":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.Numeric);
cell.SetCellValue(Convert.ToInt32(cellValue));
//cell.CellStyle = _intCellStyle;
}
break;
case "System.Int64":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.Numeric);
cell.SetCellValue(Convert.ToInt64(cellValue));
//cell.CellStyle = _intCellStyle;
}
break;
case "System.Decimal":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.Numeric);
cell.SetCellValue(Convert.ToDouble(cellValue));
//cell.CellStyle = _doubleCellStyle;
}
break;
case "System.Double":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.Numeric);
cell.SetCellValue(Convert.ToDouble(cellValue));
//cell.CellStyle = _doubleCellStyle;
}
break;
case "System.DateTime":
if (cellValue != DBNull.Value)
{
cell = file.CreateCell(iCol, CellType.String);
DateTime dateTime = Convert.ToDateTime(cellValue);
cell.SetCellValue(dateTime.ToString("dd/MM/yyyy"));
DateTime cDate = Convert.ToDateTime(cellValue);
if (cDate != null && cDate.Hour > 0)
{
//cell.CellStyle = _dateTimeCellStyle;
}
else
{
// cell.CellStyle = _dateCellStyle;
}
}
break;
default:
break;
}
iCol++;
}
iRow++;
}
using (var WritetoExcelfile = new FileStream(pFilePath, FileMode.Create, FileAccess.ReadWrite))
{
workbook.Write(WritetoExcelfile);
WritetoExcelfile.Close();
//workbook.Write(stream);
stream.Close();
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
This code you just need to copy & pest in your script and add the Namespace as following, Also change the excel file name as previously discussed.
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.SS.Util;
Please try this, this will export your data table data's faster to excel.
Note: Range "FW", that I have hard coded is because I had 179 columns.
public void UpdateExcelApplication(SqlDataTable dataTable)
{
var objects = new string[dataTable.Rows.Count, dataTable.Columns.Count];
var rowIndex = 0;
foreach (DataRow row in dataTable.Rows)
{
var colIndex = 0;
foreach (DataColumn column in dataTable.Columns)
{
objects[rowIndex, colIndex++] = Convert.ToString(row[column]);
}
rowIndex++;
}
var range = this.workSheet.Range[$"A3:FW{dataTable.Rows.Count + 2}"];
range.Value = objects;
this.workSheet.Columns.AutoFit();
this.workSheet.Rows.AutoFit();
}

Categories