如何使用C#创建Excel电子表格而不需要在运行代码的计算机上安装Excel?
当前回答
你可以试试我的SwiftExcel库。此库直接写入文件,因此非常高效。例如,您可以在几秒钟内写入100k行,而不占用任何内存。
下面是一个简单的用法示例:
using (var ew = new ExcelWriter("C:\\temp\\test.xlsx"))
{
for (var row = 1; row <= 10; row++)
{
for (var col = 1; col <= 5; col++)
{
ew.Write($"row:{row}-col:{col}", col, row);
}
}
}
其他回答
要将xls保存为xlsx格式,我们只需要从Microsoft.Office.Interop.Excel库调用SaveAs方法。该方法将采用大约16个参数,其中一个参数是文件格式。
Microsoft文档:此处另存为方法参数
我们需要传递的对象如下
wb.SaveAs(filename, 51, System.Reflection.Missing.Value,
System.Reflection.Missing.Value, false, false, 1,1, true,
System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value)
这里,51是XLSX的枚举值
对于不同文件格式的另存为,可以参考xlFileFormat
您可以在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
在我的项目中,我使用一些.net库来提取Excel文件(.xls和.xlsx)
为了导出数据,我经常使用rdlc。
要修改我使用的excel文件(尝试设置空白单元格A15时的示例代码):
关闭的XML
//Closed XML
var workbook = new XLWorkbook(sUrlFile); // load the existing excel file
var worksheet = workbook.Worksheets.Worksheet(1);
worksheet.Cell("A15").SetValue("");
workbook.Save();
铁杆XL
string sUrlFile = "G:\\ReportAmortizedDetail.xls";
WorkBook workbook = WorkBook.Load(sUrlFile);
WorkSheet sheet = workbook.WorkSheets.First();
//Select cells easily in Excel notation and return the calculated value
sheet["A15"].First().Value = "";
sheet["A15"].First().FormatString = "";
workbook.Save();
workbook.Close();
workbook = null;
SpireXLS(当我尝试时,库会打印附加页,以提供我们使用试用库的信息
string sUrlFile = "G:\\ReportAmortizedDetail.xls";
Workbook workbook = new Workbook();
workbook.LoadFromFile(sUrlFile);
//Get the 1st sheet
Worksheet sheet = workbook.Worksheets[0];
//Specify the cell range
CellRange range = sheet.Range["A15"];
//Find all matched text in the range
CellRange[] cells = range.FindAllString("hi", false, false);
//Replace text
foreach (CellRange cell in range)
{
cell.Text = "";
}
//Save
workbook.Save();
Jet Oledb公司
//ExcelTool Class
public static int ExcelUpdateSheets(string path, string sWorksheetName, string sCellLocation, string sValue)
{
int iResult = -99;
String sConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";Extended Properties='Excel 8.0;HDR=NO'";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
OleDbCommand objCmdSelect = new OleDbCommand("UPDATE [" + sWorksheetName + "$" + sCellLocation + "] SET F1=" + UtilityClass.ValueSQL(sValue), objConn);
objCmdSelect.ExecuteNonQuery();
objConn.Close();
return iResult;
}
用法:
ExcelTool.ExcelUpdateSheets(sUrlFile, "ReportAmortizedDetail", "A15:A15", "");
天冬氨酸
var workbook = new Aspose.Cells.Workbook(sUrlFile);
// access first (default) worksheet
var sheet = workbook.Worksheets[0];
// access CellsCollection of first worksheet
var cells = sheet.Cells;
// write HelloWorld to cells A1
cells["A15"].Value = "";
// save spreadsheet to disc
workbook.Save(sUrlFile);
workbook.Dispose();
workbook = null;
我重新编码了代码,现在可以创建.xls文件,稍后可以转换为Excel 2003 Open XML格式。
private static void exportToExcel(DataSet source, string fileName)
{
// Documentacion en:
// https://en.wikipedia.org/wiki/Microsoft_Office_XML_formats
// https://answers.microsoft.com/en-us/msoffice/forum/all/how-to-save-office-ms-xml-as-xlsx-file/4a77dae5-6855-457d-8359-e7b537beb1db
// https://riptutorial.com/es/openxml
const string startExcelXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"+
"<?mso-application progid=\"Excel.Sheet\"?>\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 " +
"xmlns:html=\"http://www.w3.org/TR/REC-html40\">\r\n " +
"xmlns:html=\"https://www.w3.org/TR/html401/\">\r\n " +
"<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n " +
" <Version>16.00</Version>\r\n " +
"</DocumentProperties>\r\n " +
" <OfficeDocumentSettings xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n " +
" <AllowPNG/>\r\n " +
" </OfficeDocumentSettings>\r\n " +
" <ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n " +
" <WindowHeight>9750</WindowHeight>\r\n " +
" <WindowWidth>24000</WindowWidth>\r\n " +
" <WindowTopX>0</WindowTopX>\r\n " +
" <WindowTopY>0</WindowTopY>\r\n " +
" <RefModeR1C1/>\r\n " +
" <ProtectStructure>False</ProtectStructure>\r\n " +
" <ProtectWindows>False</ProtectWindows>\r\n " +
" </ExcelWorkbook>\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=\"dd/mm/yyyy;@\"/>\r\n </Style>\r\n " +
"</Styles>\r\n ";
System.IO.StreamWriter excelDoc = null;
excelDoc = new System.IO.StreamWriter(fileName,false);
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 == 1048576)
{
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++;
}
const string endExcelOptions1 = "\r\n<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n" +
"<Selected/>\r\n" +
"<ProtectObjects>False</ProtectObjects>\r\n" +
"<ProtectScenarios>False</ProtectScenarios>\r\n" +
"</WorksheetOptions>\r\n";
excelDoc.Write(endExcelOptions1);
excelDoc.Write("</Workbook>");
excelDoc.Close();
}
我最近刚刚使用了FlexCel.NET,发现它是一个优秀的库!我对太多的软件产品不这么说。在这里进行整个销售宣传没有意义,你可以阅读他们网站上的所有功能。
这是一个商业产品,但如果你购买它,你会得到完整的源代码。所以我想,如果你真的想,你可以将它编译成你的程序集。否则,它只是一个额外的程序集来xcopy-没有配置或安装或类似的东西。
我认为,如果没有第三方库,您将找不到任何方法来做到这一点,因为.NET框架显然没有内置的支持,OLE自动化只是一个痛苦的世界。
推荐文章
- 最好的方法在asp.net强制https为整个网站?
- 将字符串转换为System.IO.Stream
- 如何从枚举中选择一个随机值?
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法