[英]Export Excel using Npoi
I am looking to export an excel sheet using NPOI library.我正在寻找使用 NPOI 库导出 excel 表。 Is there any way to insert the datatable into the sheet without losing the data format?
有什么办法可以在不丢失数据格式的情况下将数据表插入到工作表中吗?
Previously, I used to use the Gembox Spreadsheet Library.以前,我曾经使用 Gembox 电子表格库。 This worked well for me.
这对我来说效果很好。 The code for that looke like:
那个看起来像的代码:
public void ExportTest(DataSet ds)
{
SpreadsheetInfo.SetLicense("FREE-LIMITED-KEY");
ExcelFile ef = new ExcelFile();
var filename = DateTime.Now.ToString("yyyyMMdd") + "BSI_MEMBERAmendment" + ".xls";
foreach (DataTable dt in ds.Tables)
{
ExcelWorksheet ws = ef.Worksheets.Add(dt.TableName);
ws.InsertDataTable(dt,
new InsertDataTableOptions(0, 0)
{
ColumnHeaders = true,
StartRow = 0,
});
}
ef.Save(this.Response, filename);
I had to stop using the Gembox library because I need to make excel files with more than 5 sheets.我不得不停止使用 Gembox 库,因为我需要制作超过 5 张纸的 excel 文件。 Gembox, unfortunately does not allow that on a free platform.
不幸的是,Gembox 在免费平台上不允许这样做。 As such, I've switched to NPOI.
因此,我已经切换到 NPOI。
Now that I'm using the NPOI library, I've change my code to:现在我正在使用 NPOI 库,我已将代码更改为:
public void WriteExcelWithNPOI(String extension, DataSet dataSet)
{
HSSFWorkbook workbook = new HSSFWorkbook(); ;
if (extension == "xls")
{
workbook = new HSSFWorkbook();
}
else
{
throw new Exception("This format is not supported");
}
foreach (DataTable dt in dataSet.Tables)
{
var sheet1 = workbook.CreateSheet(dt.TableName);
// How can i insert the data's from dataTable in this sheet
}
using (var exportData = new MemoryStream())
{
Response.Clear();
workbook.Write(exportData);
if (extension == "xls")
{
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", "tpms_dict.xls"));
Response.BinaryWrite(exportData.GetBuffer());
}
Response.End();
}
}
The problem that I'm encountering with using the NPOI library is, all the cells in the exported excel file is formatted as text.我在使用 NPOI 库时遇到的问题是,导出的 excel 文件中的所有单元格都被格式化为文本。 I'd like to retain the format that's used in the data table.
我想保留数据表中使用的格式。 Looking for help.
寻求帮助。 Thanks in advance!!!
提前致谢!!!
To insert data from a data table, you could perhaps use this code in place of the comment " // How can i insert the data's from dataTable in this sheet ".要从数据表插入数据,您或许可以使用此代码代替注释“ // 如何在此工作表中插入来自 dataTable 的数据”。
// 1. make a header row
IRow row1 = sheet1.CreateRow(0);
for (int j = 0; j < dt.Columns.Count; j++)
{
ICell cell = row1.CreateCell(j);
string columnName = dt.Columns[j].ToString();
cell.SetCellValue(columnName);
}
// 2. loop through data
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow row = sheet1.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
{
ICell cell = row.CreateCell(j);
string columnName = dt.Columns[j].ToString();
cell.SetCellValue(dt.Rows[i][columnName].ToString());
}
}
// 3. Auto size columns
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < row1.LastCellNum; j++)
{
sheet1.AutoSizeColumn(j);
}
}
For data types, you could use the function cell.SetCellType(CellType.[TYPE HERE]);
对于数据类型,您可以使用函数
cell.SetCellType(CellType.[TYPE HERE]);
. . The type entered in the function
SetCellType
must match the data type in cell.SetCellValue()
afterwards.之后在函数
SetCellType
输入的类型必须与cell.SetCellValue()
中的数据类型匹配。
This will modify the data loop to look as follows:这将修改数据循环,如下所示:
// 2. loop through data
for (int i = 0; i < dt.Rows.Count; i++)
{
IRow row = sheet1.CreateRow(i + 1);
for (int j = 0; j < dt.Columns.Count; j++)
{
ICell cell = row.CreateCell(j);
string columnName = dt.Columns[j].ToString();
// Set the cell type
cell.SetCellType(GetCorrectCellType(dt.Rows[i][columnName].GetType()))
// Set the cell value
cell.SetCellValue(dt.Rows[i][columnName]);
}
}
// Function to return the correct cell type
public int GetCorrectCellType(Type dataType)
{
if(dataType == typeof(string))
return CellType.String;
else if(dataType == typeof(int) || dataType == typeof(double))
return CellType.Numeric;
else if(dataType == typeof(bool))
return CellType.Boolean;
else
return CellType.Unknown; // Not sure how to set Date Type --> Unknown
}
EDIT I found how set set Date values in a human readable format in this answer .编辑我发现如何在这个答案中以人类可读的格式设置日期值。
I know I am a little late here but I think it may help others, yes, there is a way to convert datatable directly to export excel without losing data format.我知道我在这里有点晚了,但我认为它可以帮助其他人,是的,有一种方法可以将数据表直接转换为导出 excel 而不会丢失数据格式。
I have developed an excel utility with the use of the NPOI package, which can我使用 NPOI 包开发了一个 excel 实用程序,它可以
Github Code repo.: https://github.com/ansaridawood/.NET-Generic-Excel-Export-Sample/tree/master/GenericExcelExport/ExcelExport Github 代码仓库: https : //github.com/ansaridawood/.NET-Generic-Excel-Export-Sample/tree/master/GenericExcelExport/ExcelExport
Looking for a code explanation, you can find it here: https://www.codeproject.com/Articles/1241654/Export-to-Excel-using-NPOI-Csharp-and-WEB-API寻找代码解释,你可以在这里找到: https : //www.codeproject.com/Articles/1241654/Export-to-Excel-using-NPOI-Csharp-and-WEB-API
It uses NPOI DLL and it has 2 cs files to include and then you are good to go它使用 NPOI DLL 并包含 2 个 cs 文件,然后您就可以开始使用了
Below is the first file for reference AbstractDataExport.cs :以下是参考AbstractDataExport.cs的第一个文件:
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
namespace GenericExcelExport.ExcelExport
{
public interface IAbstractDataExport
{
HttpResponseMessage Export(List exportData, string fileName, string sheetName);
}
public abstract class AbstractDataExport : IAbstractDataExport
{
protected string _sheetName;
protected string _fileName;
protected List _headers;
protected List _type;
protected IWorkbook _workbook;
protected ISheet _sheet;
private const string DefaultSheetName = "Sheet1";
public HttpResponseMessage Export
(List exportData, string fileName, string sheetName = DefaultSheetName)
{
_fileName = fileName;
_sheetName = sheetName;
_workbook = new XSSFWorkbook(); //Creating New Excel object
_sheet = _workbook.CreateSheet(_sheetName); //Creating New Excel Sheet object
var headerStyle = _workbook.CreateCellStyle(); //Formatting
var headerFont = _workbook.CreateFont();
headerFont.IsBold = true;
headerStyle.SetFont(headerFont);
WriteData(exportData); //your list object to NPOI excel conversion happens here
//Header
var header = _sheet.CreateRow(0);
for (var i = 0; i < _headers.Count; i++)
{
var cell = header.CreateCell(i);
cell.SetCellValue(_headers[i]);
cell.CellStyle = headerStyle;
}
for (var i = 0; i < _headers.Count; i++)
{
_sheet.AutoSizeColumn(i);
}
using (var memoryStream = new MemoryStream()) //creating memoryStream
{
_workbook.Write(memoryStream);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(memoryStream.ToArray())
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue
("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
FileName = $"{_fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
};
return response;
}
}
//Generic Definition to handle all types of List
public abstract void WriteData(List exportData);
}
}
and this the second and final file AbstractDataExportBridge.cs :这是第二个也是最后一个文件AbstractDataExportBridge.cs :
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text.RegularExpressions;
namespace GenericExcelExport.ExcelExport
{
public class AbstractDataExportBridge : AbstractDataExport
{
public AbstractDataExportBridge()
{
_headers = new List<string>();
_type = new List<string>();
}
public override void WriteData<T>(List<T> exportData)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
{
var type = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
_type.Add(type.Name);
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ??
prop.PropertyType);
string name = Regex.Replace(prop.Name, "([A-Z])", " $1").Trim(); //space separated
//name by caps for header
_headers.Add(name);
}
foreach (T item in exportData)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
IRow sheetRow = null;
for (int i = 0; i < table.Rows.Count; i++)
{
sheetRow = _sheet.CreateRow(i + 1);
for (int j = 0; j < table.Columns.Count; j++)
{
ICell Row1 = sheetRow.CreateCell(j);
string type = _type[j].ToLower();
var currentCellValue = table.Rows[i][j];
if (currentCellValue != null &&
!string.IsNullOrEmpty(Convert.ToString(currentCellValue)))
{
if (type == "string")
{
Row1.SetCellValue(Convert.ToString(currentCellValue));
}
else if (type == "int32")
{
Row1.SetCellValue(Convert.ToInt32(currentCellValue));
}
else if (type == "double")
{
Row1.SetCellValue(Convert.ToDouble(currentCellValue));
}
}
else
{
Row1.SetCellValue(string.Empty);
}
}
}
}
}
}
For a detailed explanation, refer link provided in the beginning.有关详细说明,请参阅开头提供的链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.