c# - Cell by Cell写的很慢,但是我遇到了range写的情况

标签 c# excel file-io

我有一个非常大的数组,其大小取决于外部设备,它可以是 65536 也可以是 131072 的两倍及其数据类型是 ushort

我必须将整个数据写入一个 65536 行 * 1 列的 .xlsx 文件。我以前是一个单元一个单元地写,但大约需要 4 分钟才能完成。

所以我想到了使用range approach(As given here ),我的部分代码如下:

{
    \\ VoltageFluctuations is of ushort type with 65536 values

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

    // Voltage Fluctuations
    xlWorkSheet1 = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
    xlWorkSheet1.Name = "Voltage Fluctuations";

    xlWorkSheet1.Cells[1, 1] = ("Minutes");
    xlWorkSheet1.Cells[1, 2] = ("Voltage");


    var startCell = (Excel.Range)xlWorkSheet1.Cells[2, 2];
    var endCell   = new object();
    endCell = (Excel.Range)xlWorkSheet1.Cells[65536, 2];
    var writeRange = xlWorkSheet1.get_Range(startCell, endCell);

    writeRange.set_Value(Type.Missing, VoltageFluctuations); 

    // As soon as the above line is executed my program crashes

    // Finally saving this as a .xlsx file type
}

我得到的异常是:

enter image description here

最佳答案

使用 OpenXML SDK 尝试这个问题:

对于用户界面:

  private static Worksheet GetWorksheet(SpreadsheetDocument document, string worksheetName = "Sheet1")
    {
        var sheets = document.WorkbookPart.Workbook
            .Descendants<Sheet>().Where(s => s.Name == worksheetName);
        var worksheetPart = (WorksheetPart)document.WorkbookPart
            .GetPartById(sheets.First().Id);

        return worksheetPart.Worksheet;
    }

    private static string GetColumnName(int columnIndex)
    {
        var dividend = columnIndex;
        var columnName = String.Empty;

        while (dividend > 0)
        {
            var modifier = (dividend - 1) % 26;
            columnName = Convert.ToChar(65 + modifier).AsString() + columnName;
            dividend = (dividend - modifier) / 26;
        }

        return columnName;
    }

    private static Cell CreateTextCell(int columnIndex, int rowIndex, object cellValue)
    {
        var cell = new Cell();
        var inlineString = new InlineString();
        var txt = new Text();

        cell.DataType = CellValues.InlineString;
        cell.CellReference = GetColumnName(columnIndex) + rowIndex;
        txt.Text = cellValue.AsString();

        inlineString.AppendChild(txt);
        cell.AppendChild(inlineString);

        return cell;
    }

    private static Row CreateContentRow(int rowIndex, object[] cellValues)
    {
        var row = new Row
        {
            RowIndex = (UInt32)rowIndex
        };

        for (var i = 0; i < cellValues.Length; i++)
        {
            var dataCell = CreateTextCell(i + 1, rowIndex, cellValues[i]);
            row.AppendChild(dataCell);
        }

        return row;
    }

电子表格集数据:

            var sourcePath = "Report_Template.xlsx";
        var data = File.ReadAllBytes(sourcePath);
        var memoryStream = new MemoryStream();
        memoryStream.Write(data, 0, data.Length);
            var processSettings = new MarkupCompatibilityProcessSettings
            (
            MarkupCompatibilityProcessMode.ProcessAllParts,
            FileFormatVersions.Office2007
            );
        var openSettings = new OpenSettings()
        {
            MarkupCompatibilityProcessSettings = processSettings,
            AutoSave = true
        };

        using (var spreadSheet = SpreadsheetDocument.Open(memoryStream, true, openSettings))
        {

            var worksheet = GetWorksheet(spreadSheet);
            var worksheetPart = worksheet.WorksheetPart;
            const int lastRowIndex = 1;
            var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
            var lastRow = sheetData.Elements<Row>().LastOrDefault(l => l.RowIndex == lastRowIndex);
            var reportItems=null;//Get your reoirting data...    

            if (lastRow != null)
            {
                foreach (var newRow in (from reportItem in reportItems
                                        let newRowIndex = lastRow.RowIndex + 1
                                        select CreateContentRow((int)newRowIndex, new object[] 
                    {
                        newRowIndex-lastRow.RowIndex,
                        reportItem.Column1,
                        reportItem.Column2
                {
                    sheetData.InsertAfter(newRow, lastRow);
                }

                worksheet.Save();
            }

        }

After & Before 方法,插入和附加数据的引用行和单元格...

关于c# - Cell by Cell写的很慢,但是我遇到了range写的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16250089/

相关文章:

c# - 已删除的共享驱动器组权限是否根据电子邮件地址重用?

c# - 组合框的两种方式数据绑定(bind)问题 - WPF

php - 上传 Excel Codeigniter 错误双主键

excel - Excel 公式可能超过 8,000 个字符?

excel - 在 Excel 中按月格式化行

python - 将包含python列表的文本文档读入python程序

c# - ASP.NET MVC 错误 : Object being referred to is not locked by any Client

c++ - 如何直接有效地访问非常大的文本文件?

r - 当有很多列时,使用 readr::read_csv() 导入数据时覆盖列类型

c# - 将单选按钮绑定(bind)到特定对象列表中的枚举