使用 C# 和 OpenXML 读取大型 Excel 文件

介绍

高效读取大型 Excel 文件可能具有挑战性,尤其是在处理需要高性能和可扩展性的应用程序时。Microsoft 的 OpenXML SDK 提供了一套强大的工具来处理 Office 文档(包括 Excel 文件),而无需在服务器上安装 Excel。本文将指导您使用 C# 和 OpenXML 高效读取大型 Excel 文件。

为何使用 OpenXML?

OpenXML 是办公文档(Word、Excel、PowerPoint)的开放标准,允许以编程方式操作这些文档。使用 OpenXML 的一些好处包括:

  • 性能:它直接对文件流进行操作,而无需将整个文档加载到内存中。
  • 无依赖性:无需安装 Microsoft Office。
  • 可扩展性:非常适合服务器端应用程序和批处理。

先决条件

在深入研究代码之前,请确保您已具备以下内容。

  • Visual Studio 或任何 C# IDE
  • .NET Framework 或 .NET Core SDK
  • OpenXML SDK:您可以使用命令通过 NuGet 安装它。
Install-Package DocumentFormat.OpenXml

使用 OpenXML 读取大型 Excel 文件

以下是使用 C# 和 OpenXML 读取大型 Excel 文件的分步指南。

1. 设置项目

创建一个新的 C# 控制台应用程序。

  • 打开 Visual Studio 并创建一个新的控制台应用程序(.NET Core 或 .NET Framework)。
  • 通过 NuGet 安装 OpenXML SDK。

2.打开 Excel 文件

首先,您需要打开 Excel 文件并访问要读取的工作表。使用以下代码打开 Excel 文件。

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;

namespace ReadLargeExcelFile
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "path/to/your/large/excelfile.xlsx";
            using (SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, false))
            {
                WorkbookPart workbookPart = doc.WorkbookPart;
                Sheet sheet = workbookPart.Workbook.Sheets.GetFirstChild<Sheet>();
                WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);

                IEnumerable<Row> rows = worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>();

                foreach (Row row in rows)
                {
                    foreach (Cell cell in row.Elements<Cell>())
                    {
                        string cellValue = GetCellValue(doc, cell);
                        Console.Write(cellValue + " ");
                    }
                    Console.WriteLine();
                }
            }
        }

        private static string GetCellValue(SpreadsheetDocument doc, Cell cell)
        {
            SharedStringTablePart stringTablePart = doc.WorkbookPart.SharedStringTablePart;
            string value = cell.CellValue.InnerXml;

            if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
            {
                return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
            }
            else
            {
                return value;
            }
        }
    }
}

3. 高效处理大文件

上述代码将整个工作表读入内存,这对于非常大的文件来说可能效率不高。为了更有效地处理大文件,请考虑分块处理文件或使用流式传输技术。

. 优化性能

为了优化性能,您可以

  • 流式传输文件:使用流式传输技术分部分处理文件,而不是将整个文件加载到内存中。
  • 并行处理:如果您的应用程序允许,您可以并行处理文件的不同部分。
  • 高效的数据结构:使用高效的数据结构来存储和处理数据。

下面是一个使用流式传输的示例。

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;

namespace ReadLargeExcelFile
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "path/to/your/large/excelfile.xlsx";
            using (SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, false))
            {
                WorkbookPart workbookPart = doc.WorkbookPart;
                Sheet sheet = workbookPart.Workbook.Sheets.GetFirstChild<Sheet>();
                WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);

                OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
                while (reader.Read())
                {
                    if (reader.ElementType == typeof(Row))
                    {
                        Row row = (Row)reader.LoadCurrentElement();
                        foreach (Cell cell in row.Elements<Cell>())
                        {
                            string cellValue = GetCellValue(doc, cell);
                            Console.Write(cellValue + " ");
                        }
                        Console.WriteLine();
                    }
                }
            }
        }

        private static string GetCellValue(SpreadsheetDocument doc, Cell cell)
        {
            SharedStringTablePart stringTablePart = doc.WorkbookPart.SharedStringTablePart;
            string value = cell.CellValue.InnerXml;

            if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
            {
                return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
            }
            else
            {
                return value;
            }
        }
    }
}

结论

使用 C# 和 OpenXML 读取大型 Excel 文件为需要高性能和可扩展性的应用程序提供了强大的解决方案。通过遵循本文概述的做法,您可以高效地处理存储在 Excel 文件中的大型数据集,从而使您的应用程序更高效、响应更快。OpenXML 无需安装 Office 即可操作 Office 文档,这使其成为任何开发人员工具包中的重要工具。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以使用C#OpenXML SDK来读取Word文档中指定书签标记的图表。以下是大致的步骤: 1. 导入OpenXML SDK的命名空间。例如:`using DocumentFormat.OpenXml.Packaging;`和`using DocumentFormat.OpenXml.Wordprocessing;`。 2. 打开Word文档,并使用`WordprocessingDocument`类加载文档。例如:`WordprocessingDocument doc = WordprocessingDocument.Open("document.docx", true);`。 3. 获取文档中的书签标记。可以使用`BookmarkStart`和`BookmarkEnd`元素来识别书签标记。例如,使用以下代码获取名为“bookmark1”的书签标记: ```csharp BookmarkStart bookmarkStart = doc.MainDocumentPart.Document.Body.Descendants<BookmarkStart>().Where(b => b.Name == "bookmark1").FirstOrDefault(); BookmarkEnd bookmarkEnd = doc.MainDocumentPart.Document.Body.Descendants<BookmarkEnd>().Where(b => b.Id.Value == bookmarkStart.Id.Value).FirstOrDefault(); ``` 4. 使用书签标记的位置信息,获取书签标记所在的段落和图表。例如,使用以下代码获取名为“bookmark1”的书签标记所在的段落和图表: ```csharp Paragraph paragraph = bookmarkStart.Parent as Paragraph; Drawing drawing = paragraph.Elements<Drawing>().FirstOrDefault(); ChartReference chartReference = drawing.Inline.Graphic.GraphicData.Descendants<ChartReference>().FirstOrDefault(); ``` 5. 获取图表数据,并使用相应的库(如OpenXML SDK、Excel Interop或EPPlus)进行分析和处理。例如,使用以下代码获取图表数据: ```csharp ChartPart chartPart = (ChartPart)doc.MainDocumentPart.GetPartById(chartReference.Id); OpenXmlReader reader = OpenXmlReader.Create(chartPart); while (reader.Read()) { if (reader.ElementType == typeof(SeriesText)) { string seriesText = reader.GetText(); // 处理图表数据 } } ``` 请注意,这只是一个简单的示例,实际情况可能需要根据具体的文档和需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢.锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值