嗨,我有一个包含值列表的列表容器。我希望将列表值直接导出到 Excel。有什么办法可以直接做吗?
14 回答
好的,如果你想使用 COM,这里有一个分步指南。
- 您必须安装 Excel。
- 将对您的项目的引用添加到 excel 互操作 dll。要在 .NET 选项卡上执行此操作,请选择 Microsoft.Office.Interop.Excel。可能有多个具有此名称的程序集。选择适合您的 Visual Studio 和 Excel 版本。
- 这是一个代码示例,用于创建新工作簿并用列表中的项目填充一列。
using NsExcel = Microsoft.Office.Interop.Excel;
public void ListToExcel(List<string> list)
{
//start excel
NsExcel.ApplicationClass excapp = new Microsoft.Office.Interop.Excel.ApplicationClass();
//if you want to make excel visible
excapp.Visible = true;
//create a blank workbook
var workbook = excapp.Workbooks.Add(NsExcel.XlWBATemplate.xlWBATWorksheet);
//or open one - this is no pleasant, but yue're probably interested in the first parameter
string workbookPath = "C:\test.xls";
var workbook = excapp.Workbooks.Open(workbookPath,
0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
//Not done yet. You have to work on a specific sheet - note the cast
//You may not have any sheets at all. Then you have to add one with NsExcel.Worksheet.Add()
var sheet = (NsExcel.Worksheet)workbook.Sheets[1]; //indexing starts from 1
//do something usefull: you select now an individual cell
var range = sheet.get_Range("A1", "A1");
range.Value2 = "test"; //Value2 is not a typo
//now the list
string cellName;
int counter = 1;
foreach (var item in list)
{
cellName = "A" + counter.ToString();
var range = sheet.get_Range(cellName, cellName);
range.Value2 = item.ToString();
++counter;
}
//you've probably got the point by now, so a detailed explanation about workbook.SaveAs and workbook.Close is not necessary
//important: if you did not make excel visible terminating your application will terminate excel as well - I tested it
//but if you did it - to be honest - I don't know how to close the main excel window - maybee somewhere around excapp.Windows or excapp.ActiveWindow
}
我只是写了一个简单的例子来告诉你如何命名文件、工作表和选择单元格:
var workbook = new XLWorkbook();
workbook.AddWorksheet("sheetName");
var ws = workbook.Worksheet("sheetName");
int row = 1;
foreach (object item in itemList)
{
ws.Cell("A" + row.ToString()).Value = item.ToString();
row++;
}
workbook.SaveAs("yourExcel.xlsx");
如果您愿意,可以使用所有数据创建 System.Data.DataSet 或 System.Data.DataTable,然后使用workbook.AddWorksheet(yourDataset)
or将其添加为工作集workbook.AddWorksheet(yourDataTable)
;
使用 CSV 的想法,如果它只是一个字符串列表。假设l
是您的清单:
using System.IO;
using(StreamWriter sw = File.CreateText("list.csv"))
{
for(int i = 0; i < l.Count; i++)
{
sw.WriteLine(l[i]);
}
}
使用 ClosedXml 的最简单方法。
Imports ClosedXML.Excel
var dataList = new List<string>() { "a", "b", "c" };
var workbook = new XLWorkbook(); //creates the workbook
var wsDetailedData = workbook.AddWorksheet("data"); //creates the worksheet with sheetname 'data'
wsDetailedData.Cell(1, 1).InsertTable(dataList); //inserts the data to cell A1 including default column name
workbook.SaveAs(@"C:\data.xlsx"); //saves the workbook
有关更多信息,您还可以查看 ClosedXml 的 wiki。 https://github.com/closedxml/closedxml/wiki
快速方法 - ArrayToExcel (github)
byte[] excel = myList.ToExcel();
File.WriteAllBytes("result.xlsx", excel);
将值列表导出到 Excel
- 在 nuget 下一个参考中安装
- 安装包 Syncfusion.XlsIO.Net.Core -版本 17.2.0.35
- 安装包 ClosedXML -版本 0.94.2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClosedXML;
using ClosedXML.Excel;
using Syncfusion.XlsIO;
namespace ExporteExcel
{
class Program
{
public class Auto
{
public string Marca { get; set; }
public string Modelo { get; set; }
public int Ano { get; set; }
public string Color { get; set; }
public int Peronsas { get; set; }
public int Cilindros { get; set; }
}
static void Main(string[] args)
{
//Lista Estatica
List<Auto> Auto = new List<Program.Auto>()
{
new Auto{Marca = "Chevrolet", Modelo = "Sport", Ano = 2019, Color= "Azul", Cilindros=6, Peronsas= 4 },
new Auto{Marca = "Chevrolet", Modelo = "Sport", Ano = 2018, Color= "Azul", Cilindros=6, Peronsas= 4 },
new Auto{Marca = "Chevrolet", Modelo = "Sport", Ano = 2017, Color= "Azul", Cilindros=6, Peronsas= 4 }
};
//Inizializar Librerias
var workbook = new XLWorkbook();
workbook.AddWorksheet("sheetName");
var ws = workbook.Worksheet("sheetName");
//Recorrer el objecto
int row = 1;
foreach (var c in Auto)
{
//Escribrie en Excel en cada celda
ws.Cell("A" + row.ToString()).Value = c.Marca;
ws.Cell("B" + row.ToString()).Value = c.Modelo;
ws.Cell("C" + row.ToString()).Value = c.Ano;
ws.Cell("D" + row.ToString()).Value = c.Color;
ws.Cell("E" + row.ToString()).Value = c.Cilindros;
ws.Cell("F" + row.ToString()).Value = c.Peronsas;
row++;
}
//Guardar Excel
//Ruta = Nombre_Proyecto\bin\Debug
workbook.SaveAs("Coches.xlsx");
}
}
}
您可以将它们输出到.csv 文件并在 excel 中打开该文件。够直接吗?
最直接的方法(在我看来)是简单地将 CSV 文件放在一起。如果您想进行格式化并实际写入 *.xlsx 文件,有更复杂的解决方案(和API)可以为您完成。
一种简单的方法是打开 Excel 创建包含要导出的测试数据的工作表,然后说 excel 另存为 xml 打开 xml 查看 excel 期望的 xml 格式并通过头部用导出数据替换测试数据来生成它
@lan 这是一个 simle execel 文件的 xml 文件,其中包含我用 office 2003 生成的一列值这种格式适用于 office 2003 及更高版本
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Author>Dancho</Author>
<LastAuthor>Dancho</LastAuthor>
<Created>2010-02-05T10:15:54Z</Created>
<Company>cc</Company>
<Version>11.9999</Version>
</DocumentProperties>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>13800</WindowHeight>
<WindowWidth>24795</WindowWidth>
<WindowTopX>480</WindowTopX>
<WindowTopY>105</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="6" x:FullColumns="1"
x:FullRows="1">
<Row>
<Cell><Data ss:Type="String">Value1</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Value2</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Value3</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Value4</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Value5</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">Value6</Data></Cell>
</Row>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>5</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet2">
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
<Worksheet ss:Name="Sheet3">
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
根据您要在其中执行此操作的环境,可以使用 Excel 互操作。然而,处理 COM 并确保您清理资源,否则 Excel 实例会留在您的机器上,这很麻烦。
如果您想了解更多信息,请查看此MSDN 示例。
根据您的格式,您可以自己生成 CSV 或 SpreadsheetML,这并不难。其他替代方法是使用 3rd 方库来执行此操作。显然,他们虽然花钱。
List<"classname"> getreport = cs.getcompletionreport();
var getreported = getreport.Select(c => new { demographic = c.rName);
其中cs.getcompletionreport()
参考类文件是应用程序的业务层
我希望这会有所帮助。
我知道,我参加这个聚会迟到了,但我认为这可能对其他人有所帮助。
已经发布的答案是针对 csv 的,另一个是由 Interop dll 提供的,您需要在服务器上安装 excel,每种方法都有其优缺点。这是一个选项,它将为您提供
- 完美的excel输出[不是csv]
- 完美的 excel 和您的数据类型匹配
- 无需安装excel
- 通过列表并获取 Excel 输出 :)
您可以通过使用NPOI DLL来实现这一点,它可用于 .net 和 .net 核心
脚步 :
- 导入 NPOI DLL
- 添加下面提供的第 1 节和第 2 节代码
- 好走
第 1 节
此代码执行以下任务:
- 创建新的 Excel 对象 -
_workbook = new XSSFWorkbook();
- 创建新的 Excel 工作表对象 -
_sheet =_workbook.CreateSheet(_sheetName);
- 调用
WriteData()
- 稍后解释 最后,创建和 - 返回
MemoryStream
对象
==================================================== ============================
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);
}
}
==================================================== ============================
第 2 节
在第 2 节中,我们将执行以下步骤:
- 将 List 转换为 DataTable 反射以读取属性名称,您的
- 列标题将来自这里
- 循环遍历 DataTable 以创建 excel 行
==================================================== ============================
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);
}
}
}
}
}
}
==================================================== ============================
现在您只需要通过传递您的列表来调用 WriteData() 函数,它就会为您提供您的 Excel。
我已经在 WEB API 和 WEB API Core 中对其进行了测试,效果很好。
将 List 传递给 "Write" 方法,它将列表转换为缓冲区并返回缓冲区,将下载一个文件
byte[] buffer = Write(ListData, true, "AttendenceSummary"); return File(buffer, "application/excel", reportTitle + ".xlsx");
public static byte[] Write<T>(IEnumerable<T> list, bool xlsxExtension, string sheetName = "ExportData")
{
if (list == null)
{
throw new ArgumentNullException("list");
}
XSSFWorkbook hssfworkbook = new XSSFWorkbook();
int Rowspersheet = 15000;
int TotalRows = list.Count();
int TotalSheets = TotalRows / Rowspersheet;
for (int i = 0; i <= TotalSheets; i++)
{
ISheet sheet1 = hssfworkbook.CreateSheet(sheetName + "_" + i);
IRow row = sheet1.CreateRow(0);
int index = 0;
foreach (PropertyInfo property in typeof(T).GetProperties())
{
ICellStyle cellStyle = hssfworkbook.CreateCellStyle();
IFont cellFont = hssfworkbook.CreateFont();
cellFont.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
cellStyle.SetFont(cellFont);
ICell cell = row.CreateCell(index++);
cell.CellStyle = cellStyle;
cell.SetCellValue(property.Name);
}
int rowIndex = 1;
// int rowIndex2 = 1;
foreach (T obj in list.Skip(Rowspersheet * i).Take(Rowspersheet))
{
row = sheet1.CreateRow(rowIndex++);
index = 0;
foreach (PropertyInfo property in typeof(T).GetProperties())
{
ICell cell = row.CreateCell(index++);
cell.SetCellValue(Convert.ToString(property.GetValue(obj)));
}
}
}
MemoryStream file = new MemoryStream();
hssfworkbook.Write(file);
return file.ToArray();
}
三个有用的相关代码片段:
- 带有 EPPlus 的 ListToExcel 的 AC# 扩展方法:
public static void ListToExcel<T>(this IList<T> list, string filename, bool isRtl)
{
var response = HttpContext.Current.Response;
var path = HttpUtility.UrlEncode(filename + ".xlsx", System.Text.Encoding.UTF8);
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet worksheet = pck.Workbook.Worksheets.Add(filename);
worksheet.Cells["A1"].LoadFromCollection<T>(list, true);
//--------------------------------------------Create Rtl
if (isRtl)
worksheet.View.RightToLeft = true;
//--------------------------------------------Create AutoFilter
worksheet.Cells[worksheet.Dimension.Address].AutoFilter = true;
//--------------------------------------------Create Format as table
//create a range for the table
ExcelRange range = worksheet.Cells[1, 1, worksheet.Dimension.End.Row, worksheet.Dimension.End.Column];
//add a table to the range
var tab = worksheet.Tables.Add(range, "Table1");
//format the table
tab.TableStyle = TableStyles.Medium2;
//--------------------------------------------
var ms = new System.IO.MemoryStream();
pck.SaveAs(ms);
ms.WriteTo(response.OutputStream);
response.Clear();
//response.ContentType = "application/vnd.ms-excel"; //xls
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //xlsx
response.AddHeader("content-disposition", String.Format("attachment;filename={0}", Path.GetFileName(path)));
response.BinaryWrite(pck.GetAsByteArray());
response.Flush();
response.End();
}
注意:使用“Install-Package EPPlus”安装 EPPlus
- 带有 Microsoft.Office.Interop.Excel 的 ListToExcel 的 AC# 扩展方法:
public static void ListToExcel<T>(this IList<T> list, string filename)
{
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
app.Visible = false;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = filename;
PropertyInfo[] properties = typeof(T).GetProperties();
for (int i = 0; i < properties.Length; i++)
{
worksheet.Cells[1, i + 1] = properties[i].Name;
worksheet.Cells[1, i + 1].AutoFilter();
}
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
for (int j = 0; j < properties.Length; j++)
{
var prop = properties[j];
worksheet.Cells[i + 2, j + 1] = prop.GetValue(item);
}
}
var path = System.Web.HttpContext.Current.Server.MapPath("~/" + filename + ".xlsx");
if (File.Exists(path))
File.Delete(path);
worksheet.SaveAs(path);
workbook.Close();
app.Quit();
var response = HttpContext.Current.Response;
using (FileStream fs = File.OpenRead(path))
{
int length = (int)fs.Length;
byte[] buffer;
using (BinaryReader br = new BinaryReader(fs))
{
buffer = br.ReadBytes(length);
}
response.Clear();
response.Buffer = true;
//response.ContentType = "application/vnd.ms-excel"; //xls
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //xlsx
response.AddHeader("content-disposition", String.Format("attachment;filename={0}", Path.GetFileName(path)));
response.BinaryWrite(buffer);
response.Flush();
response.End();
}
}
注意:如果您使用 Microsoft.Office.Interop.Excel 必须在客户端安装 Office。
- ListToCsv 的 AC# 扩展方法:
public static void ListToCsv<T>(this IList<T> list, string filename)
{
string StringHeaders = "";
string StringRows = "";
PropertyInfo[] properties = typeof(T).GetProperties();
for (int i = 0; i < properties.Length - 1; i++)
{
StringHeaders += properties[i].Name + ",";
}
var lastPropName = properties[properties.Length - 1].Name;
StringHeaders += lastPropName + Environment.NewLine;
foreach (var item in list)
{
for (int i = 0; i < properties.Length - 1; i++)
{
var prop = properties[i];
StringRows += prop.GetValue(item) + ",";
}
var lastPropInfo = properties[properties.Length - 1];
StringRows += lastPropInfo.GetValue(item) + Environment.NewLine;
}
var response = HttpContext.Current.Response;
response.Clear();
response.AddHeader("content-disposition", "attachment; filename=" + filename + ".csv");
response.AddHeader("content-type", "text/csv");
using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8))
{
writer.WriteLine(StringHeaders + StringRows);
}
response.Flush();
response.End();
}