乘風破浪,遇見最佳跨平臺跨終端框架.Net Core/.Net生態 - 微軟開源組件Open-XML-SDK,解析Office文件

Open-XML-SDK

image

https://github.com/OfficeDev/Open-XML-SDK

Open XML SDK提供了用於處理Office Word、Excel和PowerPoint文檔的工具。

它支持以下情況。

  • 高性能地生成文字處理文檔、電子表格和演示文稿。
  • 文檔修改,如添加、更新和刪除內容和元數據。
  • 使用正則表達式搜索和替換內容。
  • 將一個文件分割(粉碎)爲多個文件,並將多個文件合併爲一個文件。
  • 更新Word/PowerPoint中圖表的緩存數據和嵌入式電子表格。

獲取Nuget包

https://www.nuget.org/packages/DocumentFormat.OpenXml.Linq

dotnet add package DocumentFormat.OpenXml.Linq

image

簡單使用

讀取Excel文件

public class ReadSheetCommand : IRequest<HandlerResult<IEnumerable<string>>>
{
    /// <summary>
    /// 目標路徑
    /// </summary>
    public string TargetPath { get; private set; }

    /// <summary>
    /// 目標頁面
    /// </summary>
    public string TargetSheet { get; private set; }

    /// <summary>
    /// 構造函數
    /// </summary>
    /// <param name="targetPath">目標路徑</param>
    /// <param name="targetSheet">目標頁面</param>
    public ReadSheetCommand(string targetPath, string targetSheet)
    {
        TargetPath = targetPath;
        TargetSheet = targetSheet;
    }
}
internal class ReadSheetCommandHandler : IRequestHandler<ReadSheetCommand, HandlerResult<IEnumerable<string>>>
{
    public async Task<HandlerResult<IEnumerable<string>>> Handle(ReadSheetCommand request, CancellationToken cancellationToken)
    {
        if(request is null || string.IsNullOrEmpty(request.TargetPath) || File.Exists(request.TargetPath) == false)
        {
            return await Task.FromResult(HandlerResult<IEnumerable<string>>.Failure("打開文件不存在"));
        }

        var allLines = new List<string>();
        try
        {
            // 創建SpreadsheetDocument對象,打開文件並且只讀
            using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(request.TargetPath, false))
            {
                var wbPart = mySpreadsheet.WorkbookPart;

                Sheet targetSheet;
                if(!string.IsNullOrEmpty(request.TargetSheet))
                {
                    targetSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault(x => x.Name == request.TargetSheet);
                }
                else
                {
                    targetSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault();
                }

                var wsPart = wbPart.GetPartById(targetSheet.Id) as WorksheetPart;
                if(wsPart is not null)
                {
                    var wsRows = wsPart.Worksheet.Descendants<Row>();
                    foreach (var wsRow in wsRows)
                    {
                        var sb = new StringBuilder();
                        foreach (Cell wsCell in wsRow)
                        {
                            var wsValue = GetCellValue(wbPart, wsCell);
                            sb.Append(wsValue);
                            sb.Append(',');
                        }
                        allLines.Add(sb.ToString());
                    }
                }
            }
        }
        catch (Exception ex)
        {
            if(ex.Message.Contains("End of Central Directory record could not be found."))
            {
                return HandlerResult<IEnumerable<string>>.Failure("文件打開失敗,已損壞或者格式錯誤");
            }
            else if (ex.Message.Contains("because it is being used by another process."))
            {
                return HandlerResult<IEnumerable<string>>.Failure("文件打開失敗,它被另外一個進程佔用了");
            }
            System.Console.WriteLine(ex.Message);
        }

        return await Task.FromResult(HandlerResult<IEnumerable<string>>.OK(allLines));
    }

    public static string GetCellValue(WorkbookPart wbPart, Cell theCell)
    {
        string value = theCell.InnerText;
        if (theCell.DataType != null)
        {
            switch (theCell.DataType.Value)
            {
                case CellValues.SharedString:
                    var stringTable = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
                    if (stringTable != null)
                    {
                        value = stringTable.SharedStringTable.ElementAt(int.Parse(value)).InnerText;
                    }
                    break;

                case CellValues.Boolean:
                    switch (value)
                    {
                        case "0":
                            value = "FALSE";
                            break;
                        default:
                            value = "TRUE";
                            break;
                    }
                    break;
            }
        }
        return value;
    }
}

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章