如何将数据导出到Excel文件

23

我有一个包含数据的Excel文件。我想将其中特定的行写入到另一个由代码创建的Excel文件中。顺便说一下,这些行的索引值已经存储在一个列表中。我该如何实现?


1
你已经成功在代码中创建了 Excel 文件吗? - Jethro
是的,我使用"FileInfo"类创建了新的Excel文件,现在我想在其中插入一些行。 - M_Mogharrabi
你的意思是你做了类似这样的事情。FileInfo fi = new FileInfo("c:\myfile.xls"); fi.Create(); - Jethro
是的,没错。但是我怎么往里面插入数据呢? - M_Mogharrabi
2
如果您创建了这样的文件,则不是真正的Excel文件,请查看此教程以了解如何创建它。http://csharp.net-informations.com/excel/csharp-create-excel.htm - Jethro
显示剩余2条评论
7个回答

17

一个很好的Microsoft Open XML SDK示例 - Open XML Writer可以在http://polymathprogrammer.com/2012/08/06/how-to-properly-use-openxmlwriter-to-write-large-excel-files/找到。或者查看Stack Overflow解决方案https://dev59.com/c2XWa4cB1Zd3GeqPQtSD#42304339 - Greg

7
 private void button1_Click(object sender, EventArgs e)
    {
        Excel.Application xlApp ;
        Excel.Workbook xlWorkBook ;
        Excel.Worksheet xlWorkSheet ;
        object misValue = System.Reflection.Missing.Value;

        xlApp = new Excel.ApplicationClass();
        xlWorkBook = xlApp.Workbooks.Add(misValue);

        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
        xlWorkSheet.Cells[1, 1] = "http://csharp.net-informations.com";

        xlWorkBook.SaveAs("csharp-Excel.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
        xlWorkBook.Close(true, misValue, misValue);
        xlApp.Quit();

        releaseObject(xlWorkSheet);
        releaseObject(xlWorkBook);
        releaseObject(xlApp);

        MessageBox.Show("Excel file created , you can find the file c:\\csharp-Excel.xls");
    }

    private void releaseObject(object obj)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch (Exception ex)
        {
            obj = null;
            MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
        }
        finally
        {
            GC.Collect();
        }
    }

上面的代码直接摘自 csharp.net 网站,请访问该网站查看。

3
请注意,如果您正在通过 Web 应用程序进行导出,请勿这样做。在 Web 服务器上使用 Excel 自动化将会导致问题。如果必须使用自动化,请使用 MSMQ 或其他工具来触发进程外的导出操作。 - Josh Anderson
不仅如此,它需要在服务器上安装Office,这意味着您必须拥有许可证。我建议使用像这样的库:http://www.carlosag.net/Tools/ExcelXmlWriter/ - Icarus
@jethro,谢谢,但是我用GemBox.SpreadSheet组件解决了我的问题。它可以将整个DataTable添加到Excel文件中。 - M_Mogharrabi

5

您是否听说过NPOI,它是一个.NET库,无需安装Microsoft Office即可读写Office格式。没有COM+,没有Interop。Github页面

这是我的Excel导出类。

/*
 * User: TMPCSigit aswzen@gmail.com
 * Date: 25/11/2019
 * Time: 11:28
 * 
 */
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace Employee_Manager
{
    public static class ExportHelper
    {       
        public static void WriteCell( ISheet sheet, int columnIndex, int rowIndex, string value )
        {
            var row = sheet.GetRow( rowIndex ) ?? sheet.CreateRow( rowIndex );
            var cell = row.GetCell( columnIndex ) ?? row.CreateCell( columnIndex );

            cell.SetCellValue( value );
        }
        public static void WriteCell( ISheet sheet, int columnIndex, int rowIndex, double value )
        {
            var row = sheet.GetRow( rowIndex ) ?? sheet.CreateRow( rowIndex );
            var cell = row.GetCell( columnIndex ) ?? row.CreateCell( columnIndex );

            cell.SetCellValue( value );
        }
        public static void WriteCell( ISheet sheet, int columnIndex, int rowIndex, DateTime value )
        {
            var row = sheet.GetRow( rowIndex ) ?? sheet.CreateRow( rowIndex );
            var cell = row.GetCell( columnIndex ) ?? row.CreateCell( columnIndex );

            cell.SetCellValue( value );
        }
        public static void WriteStyle( ISheet sheet, int columnIndex, int rowIndex, ICellStyle style )
        {
            var row = sheet.GetRow( rowIndex ) ?? sheet.CreateRow( rowIndex );
            var cell = row.GetCell( columnIndex ) ?? row.CreateCell( columnIndex );

            cell.CellStyle = style;
        }

        public static IWorkbook CreateNewBook( string filePath )
        {
            IWorkbook book;
            var extension = Path.GetExtension( filePath );

            // HSSF => Microsoft Excel(xls形式)(excel 97-2003)
            // XSSF => Office Open XML Workbook形式(xlsx形式)(excel 2007以降)
            if( extension == ".xls" ) {
                book = new HSSFWorkbook();
            }
            else if( extension == ".xlsx" ) {
                book = new XSSFWorkbook();
            }
            else {
                throw new ApplicationException( "CreateNewBook: invalid extension" );
            }

            return book;
        }
        public static void createXls(DataGridView dg){
            try {
                string filePath = "";
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "Excel XLS (*.xls)|*.xls";
                sfd.FileName = "Export.xls";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    filePath = sfd.FileName;
                    var book = CreateNewBook( filePath );
                    book.CreateSheet( "Employee" );
                    var sheet = book.GetSheet( "Employee" );
                    int columnCount = dg.ColumnCount;
                    string columnNames = "";
                    string[] output = new string[dg.RowCount + 1];
                    for (int i = 0; i < columnCount; i++)
                    {
                        WriteCell( sheet, i, 0, SplitCamelCase(dg.Columns[i].Name.ToString()) );
                    }
                    for (int i = 0; i < dg.RowCount; i++)
                    {
                        for (int j = 0; j < columnCount; j++)
                        {
                            var celData =  dg.Rows[i].Cells[j].Value;
                            if(celData == "" || celData == null){
                                celData = "-";
                            }
                            if(celData.ToString() == "System.Drawing.Bitmap"){
                                celData = "Ada";
                            }
                            WriteCell( sheet, j, i+1, celData.ToString() );
                        }
                    }
                    var style = book.CreateCellStyle();
                    style.DataFormat = book.CreateDataFormat().GetFormat( "yyyy/mm/dd" );
                    WriteStyle( sheet, 0, 4, style );
                    using( var fs = new FileStream( filePath, FileMode.Create ) ) {
                        book.Write( fs );
                    }
                }
            }
            catch( Exception ex ) {
                Console.WriteLine( ex );
            }
        }
        public static string SplitCamelCase(string input)
        {
            return Regex.Replace(input, "(?<=[a-z])([A-Z])", " $1", RegexOptions.Compiled);
        }
    }
}

2
在为此进行了太长时间的研究(并拒绝了付费库)之后,我可以证实NPOI是一个不错且易于使用的选择。 - Niels Abildgaard

2

我使用interop打开Excel并在数据完成后修改列宽。如果您使用interop将数据分离到新的Excel工作簿中(如果这是您想要的),则速度非常慢。相反,我生成了一个.CSV,然后在Excel中打开了.CSV。这有自己的问题,但我发现这是最快的方法。

首先,将.CSV转换:

Original Answer译成“最初的回答”

// Convert array data into CSV format.
// Modified from http://csharphelper.com/blog/2018/04/write-a-csv-file-from-an-array-in-c/.
private string GetCSV(List<string> Headers, List<List<double>> Data)
{
    // Get the bounds.
    var rows = Data[0].Count;
    var cols = Data.Count;
    var row = 0;

    // Convert the array into a CSV string.
    StringBuilder sb = new StringBuilder();

    // Add the first field in this row.
    sb.Append(Headers[0]);

    // Add the other fields in this row separated by commas.
    for (int col = 1; col < cols; col++)
        sb.Append("," + Headers[col]);

    // Move to the next line.
    sb.AppendLine();

    for (row = 0; row < rows; row++)
    {
        // Add the first field in this row.
        sb.Append(Data[0][row]);

        // Add the other fields in this row separated by commas.
        for (int col = 1; col < cols; col++)
            sb.Append("," + Data[col][row]);

        // Move to the next line.
        sb.AppendLine();
    }

    // Return the CSV format string.
    return sb.ToString();
}

然后,将其导出到Excel:
public void ExportToExcel()
{
    // Initialize app and pop Excel on the screen.
    var excelApp = new Excel.Application { Visible = true };

    // I use unix time to give the files a unique name that's almost somewhat useful.
    DateTime dateTime = DateTime.UtcNow;
    long unixTime = ((DateTimeOffset)dateTime).ToUnixTimeSeconds();
    var path = @"C:\Users\my\path\here" + unixTime + ".csv";

    var csv = GetCSV();
    File.WriteAllText(path, csv);

    // Create a new workbook and get its active sheet.
    excelApp.Workbooks.Open(path);

    var workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
        
    // iterate over each value and throw it in the chart
    for (var column = 0; column < Data.Count; column++)
    {
        ((Excel.Range)workSheet.Columns[column + 1]).AutoFit();
    }

    currentSheet = workSheet;
}

你需要安装一些东西...
  1. 从解决方案资源管理器中右键单击解决方案,选择“管理 NuGet 包” - 添加 Microsoft.Office.Interop.Excel

  2. 如果您按照interop想要的方式创建了项目,则它实际上可能已经起作用了。 如果仍然不起作用,则必须在其他类别中创建新项目。 在“新建”>“项目”下,选择“Visual C#”>“Windows桌面”>“控制台应用程序”。否则,interop工具将无法正常工作。

如果我忘记任何内容,请看我的“using”语句:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;

2
你可以使用ExcelDataReader来读取现有的Excel文件:
using (var stream = File.Open("C:\\temp\\input.xlsx", FileMode.Open, FileAccess.Read))
{
    using (var reader = ExcelReaderFactory.CreateReader(stream))
    {
        while (reader.Read())
        {
            for (var i = 0; i < reader.FieldCount; i++)
            {
                var value = reader.GetValue(i)?.ToString();
            }
        }
    }
}

在收集到所有所需数据后,您可以尝试使用SwiftExcel库将其导出到新的Excel文件中:
using (var ew = new ExcelWriter("C:\\temp\\output.xlsx"))
{
    for (var i = 1; i < 10; i++)
    {
        ew.Write("your_data", i, 1);
    }
}

Nuget命令用于安装两个库:

Install-Package ExcelDataReader

Install-Package SwiftExcel


1
我也曾遇到类似的问题,涉及使用C#将数据导出到Excel电子表格中。我尝试了许多不同的方法,使用外部DLL,但没有成功。
对于导出功能,您不需要使用任何与外部DLL相关的内容。相反,只需保留响应的标头和内容类型即可。
这是一篇我发现非常有用的文章。该文章介绍了如何使用ASP.NET将数据导出到Excel电子表格中。

http://www.icodefor.net/2016/07/export-data-to-excel-sheet-in-asp-dot-net-c-sharp.html


有趣的方法 - 创建一个HTML表格,然后用Excel打开它。 - Greg Gum

1
使用 Aspose.Cells 库 for .NET,您可以轻松地从一个 Excel 文档中导出特定行和列的数据到另一个文档。以下代码示例展示了如何在 C# 语言中实现此功能。
// Open the source excel file.
Workbook srcWorkbook = new Workbook("Source_Workbook.xlsx");

// Create the destination excel file.
Workbook destWorkbook = new Workbook();
   
// Get the first worksheet of the source workbook.
Worksheet srcWorksheet = srcWorkbook.Worksheets[0];

// Get the first worksheet of the destination workbook.
Worksheet desWorksheet = destWorkbook.Worksheets[0];

// Copy the second row of the source Workbook to the first row of destination Workbook.
desWorksheet.Cells.CopyRow(srcWorksheet.Cells, 1, 0);

// Copy the fourth row of the source Workbook to the second row of destination Workbook.
desWorksheet.Cells.CopyRow(srcWorksheet.Cells, 3, 1);

// Save the destination excel file.
destWorkbook.Save("Destination_Workbook.xlsx");

Copy Rows Data from one Excel Document to another

以下博客文章详细解释了如何从不同的来源导出数据到Excel文档中。
https://blog.conholdate.com/2020/08/10/export-data-to-excel-in-csharp/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接