如何使用C#创建Excel电子表格而不需要在运行代码的计算机上安装Excel?
当前回答
您可以在Visual Studio上安装OpenXml nuget包。以下是将数据表导出到excel文件的代码:
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Public Class ExportExcelClass
Public Sub New()
End Sub
Public Sub ExportDataTable(ByVal table As DataTable, ByVal exportFile As String)
' Create a spreadsheet document by supplying the filepath.
' By default, AutoSave = true, Editable = true, and Type = xlsx.
Dim spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Create(exportFile, SpreadsheetDocumentType.Workbook)
' Add a WorkbookPart to the document.
Dim workbook As WorkbookPart = spreadsheetDocument.AddWorkbookPart
workbook.Workbook = New Workbook
' Add a WorksheetPart to the WorkbookPart.
Dim Worksheet As WorksheetPart = workbook.AddNewPart(Of WorksheetPart)()
Worksheet.Worksheet = New Worksheet(New SheetData())
' Add Sheets to the Workbook.
Dim sheets As Sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())
Dim data As SheetData = Worksheet.Worksheet.GetFirstChild(Of SheetData)()
Dim Header As Row = New Row()
Header.RowIndex = CType(1, UInt32)
For Each column As DataColumn In table.Columns
Dim headerCell As Cell = createTextCell(table.Columns.IndexOf(column) + 1, 1, column.ColumnName)
Header.AppendChild(headerCell)
Next
data.AppendChild(Header)
Dim contentRow As DataRow
For i As Integer = 0 To table.Rows.Count - 1
contentRow = table.Rows(i)
data.AppendChild(createContentRow(contentRow, i + 2))
Next
End Sub
Private Function createTextCell(ByVal columnIndex As Integer, ByVal rowIndex As Integer, ByVal cellValue As Object) As Cell
Dim cell As Cell = New Cell()
cell.DataType = CellValues.InlineString
cell.CellReference = getColumnName(columnIndex) + rowIndex.ToString
Dim inlineString As InlineString = New InlineString()
Dim t As Text = New Text()
t.Text = cellValue.ToString()
inlineString.AppendChild(t)
cell.AppendChild(inlineString)
Return cell
End Function
Private Function createContentRow(ByVal dataRow As DataRow, ByVal rowIndex As Integer) As Row
Dim row As Row = New Row With {
.rowIndex = CType(rowIndex, UInt32)
}
For i As Integer = 0 To dataRow.Table.Columns.Count - 1
Dim dataCell As Cell = createTextCell(i + 1, rowIndex, dataRow(i))
row.AppendChild(dataCell)
Next
Return row
End Function
Private Function getColumnName(ByVal columnIndex As Integer) As String
Dim dividend As Integer = columnIndex
Dim columnName As String = String.Empty
Dim modifier As Integer
While dividend > 0
modifier = (dividend - 1) Mod 26
columnName = Convert.ToChar(65 + modifier).ToString() & columnName
dividend = CInt(((dividend - modifier) / 26))
End While
Return columnName
End Function
End Class
其他回答
下面是使用LINQ to XML完成此操作的方法,并提供示例代码:
用LINQ to XML快速导入和导出Excel数据
它有点复杂,因为您必须导入名称空间等等,但它确实可以避免任何外部依赖。
(当然,它是VB.NET,而不是C#,但您可以始终在自己的项目中隔离VB.NET内容,以使用XML文字,并使用C#执行其他所有操作。)
我编写了一个简单的代码,通过使用System.IO.StreamWriter将数据集导出到excel,而不使用excel对象。
下面是代码,它将从数据集中读取所有表,并将它们逐一写入工作表。我从这篇文章中得到了帮助。
public static void exportToExcel(DataSet source, string fileName)
{
const string endExcelXML = "</Workbook>";
const string startExcelXML = "<xml version>\r\n<Workbook " +
"xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
"xmlns:x=\"urn:schemas- microsoft-com:office:" +
"excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
"office:spreadsheet\">\r\n <Styles>\r\n " +
"<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
"<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
"\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
"\r\n <Protection/>\r\n </Style>\r\n " +
"<Style ss:ID=\"BoldColumn\">\r\n <Font " +
"x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
" ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"Decimal\">\r\n <NumberFormat " +
"ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
"ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
"ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
"</Styles>\r\n ";
System.IO.StreamWriter excelDoc = null;
excelDoc = new System.IO.StreamWriter(fileName);
int sheetCount = 1;
excelDoc.Write(startExcelXML);
foreach (DataTable table in source.Tables)
{
int rowCount = 0;
excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
excelDoc.Write("<Table>");
excelDoc.Write("<Row>");
for (int x = 0; x < table.Columns.Count; x++)
{
excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
excelDoc.Write(table.Columns[x].ColumnName);
excelDoc.Write("</Data></Cell>");
}
excelDoc.Write("</Row>");
foreach (DataRow x in table.Rows)
{
rowCount++;
//if the number of rows is > 64000 create a new page to continue output
if (rowCount == 64000)
{
rowCount = 0;
sheetCount++;
excelDoc.Write("</Table>");
excelDoc.Write(" </Worksheet>");
excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
excelDoc.Write("<Table>");
}
excelDoc.Write("<Row>"); //ID=" + rowCount + "
for (int y = 0; y < table.Columns.Count; y++)
{
System.Type rowType;
rowType = x[y].GetType();
switch (rowType.ToString())
{
case "System.String":
string XMLstring = x[y].ToString();
XMLstring = XMLstring.Trim();
XMLstring = XMLstring.Replace("&", "&");
XMLstring = XMLstring.Replace(">", ">");
XMLstring = XMLstring.Replace("<", "<");
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write(XMLstring);
excelDoc.Write("</Data></Cell>");
break;
case "System.DateTime":
//Excel has a specific Date Format of YYYY-MM-DD followed by
//the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
//The Following Code puts the date stored in XMLDate
//to the format above
DateTime XMLDate = (DateTime)x[y];
string XMLDatetoString = ""; //Excel Converted Date
XMLDatetoString = XMLDate.Year.ToString() +
"-" +
(XMLDate.Month < 10 ? "0" +
XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
"-" +
(XMLDate.Day < 10 ? "0" +
XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
"T" +
(XMLDate.Hour < 10 ? "0" +
XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
":" +
(XMLDate.Minute < 10 ? "0" +
XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
":" +
(XMLDate.Second < 10 ? "0" +
XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
".000";
excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
"<Data ss:Type=\"DateTime\">");
excelDoc.Write(XMLDatetoString);
excelDoc.Write("</Data></Cell>");
break;
case "System.Boolean":
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.Byte":
excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
"<Data ss:Type=\"Number\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.Decimal":
case "System.Double":
excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
"<Data ss:Type=\"Number\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.DBNull":
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write("");
excelDoc.Write("</Data></Cell>");
break;
default:
throw (new Exception(rowType.ToString() + " not handled."));
}
}
excelDoc.Write("</Row>");
}
excelDoc.Write("</Table>");
excelDoc.Write(" </Worksheet>");
sheetCount++;
}
excelDoc.Write(endExcelXML);
excelDoc.Close();
}
一个非常轻量级的选项可能是使用HTML表。只需在文件中创建head、body和table标记,然后将其另存为扩展名为.xls的文件。您可以使用Microsoft特定的属性来设置输出样式,包括公式。
我意识到,您可能没有在web应用程序中对此进行编码,但这里有一个通过HTML表组成Excel文件的示例。如果您正在编写控制台应用程序、桌面应用程序或服务,则可以使用此技术。
我也投票支持GemBox.Spreadsheet。
非常快速且易于使用,网站上有大量示例。
以全新的执行速度完成了我的报告任务。
http://www.codeproject.com/KB/cs/Excel_and_C_.aspx<=为什么不使用内置的windows功能,只需在服务器上安装office,您安装的任何应用程序都可以自动化。
使用本机方法就容易多了。
如果安装了它,你就可以使用它,这是windows中最棒、使用率最低的功能,在过去的好日子里,它被称为COM,它为你节省了大量时间和痛苦。
或者更简单地使用ref lib MS供应品-http://csharp.net-informations.com/excel/csharp-create-excel.htm
推荐文章
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法
- 如何从字符串中删除新的行字符?
- 如何设置一个默认值与Html.TextBoxFor?
- 检查属性是否有属性
- 格式化XML字符串以打印友好的XML字符串
- 返回内容与IHttpActionResult非ok响应
- 从IEnumerable<KeyValuePair<>>重新创建字典
- c#测试用户是否有对文件夹的写权限