【问题标题】:OpenXML Writing Values to Empty Cells in ExcelOpenXML 将值写入 Excel 中的空单元格
【发布时间】:2017-05-29 07:39:15
【问题描述】:

我已经知道如何以我想要的格式将字符串数组的内容写入 Excel,但现在我无法确保它不会覆盖 Excel 文件中已填充的单元格。

目前我正在尝试先读取 Excel 文件的内容,然后根据没有值的位置进行插入。这是我目前拥有的。

private static void WriteToExcel(string[] contents, char[] desiredColumns)
{
    string filePath = @"D:\Folder\test.xlsx";
    try
    {
        using (SpreadsheetDocument StatsCollection = SpreadsheetDocument.Open(filePath, true))
        {
            WorkbookPart bookPart = StatsCollection.WorkbookPart;
            string sheetName = "Sheet1";
            SharedStringTablePart sstpart = bookPart.GetPartsOfType<SharedStringTablePart>().First();
            SharedStringTable sst = sstpart.SharedStringTable;
            Sheet mySheet = bookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).FirstOrDefault();
            WorksheetPart sheetPart = (WorksheetPart)(bookPart.GetPartById(mySheet.Id));
            Worksheet sheet = sheetPart.Worksheet;
            var rows = sheet.Descendants<Row>();
            foreach (Row row in rows)
            {
                foreach (Cell currentCell in row.Elements<Cell>())
                {
                    int totalRows = contents.Length / 15;
                    int contentsIndex = 0;
                    for (uint indexRow = 1; indexRow <= totalRows; indexRow++)
                    {
                        for (int indexCol = 1; indexCol < 16; indexCol++)
                        {
                            SharedStringTablePart shareStringPart;
                            if (StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
                            {
                                shareStringPart = StatsCollection.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
                            }
                            else
                            {
                                shareStringPart = StatsCollection.WorkbookPart.AddNewPart<SharedStringTablePart>();
                            }
                            int index = InsertSharedStringItem(contents[contentsIndex], shareStringPart);
                            if (currentCell.CellValue.InnerText == "")
                            {
                                Cell newCell = InsertCellInWorksheet(desiredColumns[indexCol - 1].ToString(), indexRow, sheetPart);
                                if (IsNumeric(contents[contentsIndex]))
                                {
                                    newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
                                    newCell.CellValue = new CellValue(contents[contentsIndex]);
                                }
                                else
                                {
                                    newCell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
                                    newCell.CellValue = new CellValue(index.ToString());
                                }
                            }
                            else
                            {
                                break;
                            }
                            sheetPart.Worksheet.Save();
                            contentsIndex++;
                        }
                    }
                }
            }
        }
        Console.WriteLine("Copy Complete.");
    }
    catch (Exception ex)
    {
        Console.WriteLine("Cannot find output Excel file.\n" + ex.Message);
    }
}

我的想法是,如果我可以使用代码读取我找到的 Excel 工作表上的信息here,然后我可以插入null 的位置。一旦我确定某些东西是否为空,我就会从最内部的循环(处理我的列)中中断以增加我的外部循环(处理行)。但是,这似乎不起作用。我已经确认我实际上正在阅读表格中的信息,我似乎无法据此写出。

为什么我可以读取文件的内容,但不能根据其中的单元格进行写入?

更新:

对于遇到此问题的任何人,我最终切换到 Microsoft.Office.Interop 以将我的数据附加到 Excel 文件的末尾。我不愿将其作为答案,因为它没有回答如何在 OpenXML 中执行此操作,这是我的问题。但是,如果有答案,其他人可能会觉得这很有用。

【问题讨论】:

    标签: c# excel openxml


    【解决方案1】:

    这个函数试图从一个单元格中获取一个值

    如果单元格有 SharedStringValue,它将返回该值,或者它只是一个数字

    如果没有值则返回" "

    public static string GetCellV(Cell cell, SharedStringTable ss)
        {
            string cellV = null;
    
            try
            {
                cellV = cell.CellValue.InnerText;
                if (cell.DataType != null
                  && cell.DataType.Value == CellValues.SharedString)
                {
                    cellV = ss.ElementAt(Int32.Parse(cellV)).InnerText;
                }
                else
                {
    
                    cellV = cell.CellValue.InnerText;
                }
            }
            catch (Exception)
            {
                cellV = " ";
            }
    
            return cellV;
        }
    

    我相信您可以根据需要编辑最后一部分。

    注意:

    Interop 资源不是很丰富,执行起来确实很慢,请注意执行完成后未关闭的 Excel 进程。

    Open XML 更快,因为它直接编辑 XML 代码。

    【讨论】:

    • 我听说 OpenXML 比 Interop 更好,但我遇到了 .xls.xlsx 的一些问题以及上述问题,所以当时切换到 Interop 更快。更多人可以帮助我。
    • 明智的选择,如果您需要再次使用这样的 excel 包,请查看 EPPlus:epplus.codeplex.com
    猜你喜欢
    • 1970-01-01
    • 2016-01-13
    • 2018-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    相关资源
    最近更新 更多