0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NET(C#)でエクセルの値を取得する_OpenXml

Posted at

.NET(C#)のライブラリOpenXmlを使ってエクセルの値を取得してみます。

OpenXmlを使う準備

環境

vscode
.net8

コンソールアプリ

dotnet new console -n TestOpenXml
cd TestOpenXml
dotnet add package DocumentFormat.OpenXml

コード内容

エクセルの文字取得

private static string GetExcelValue(string fileName)
{
    //すでに開いているExcelファイルを開けるようにする
    var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    using var document = SpreadsheetDocument.Open(fs, false);
    var wbPart = document.WorkbookPart;
    var sheets = wbPart?.Workbook?.Sheets.Cast<Sheet>();
    if (sheets is null) return null;

    // セルの値取得
    var cellsValue = sheets.SelectMany(sheet => ((WorksheetPart)wbPart!.GetPartById(sheet.Id!))
            .Worksheet.Descendants<Cell>()
            .Select(cell => GetCellValue(document, cell))
            .Where(x => x is not null));

    // オブジェクトの値取得
    var objectsValue = sheets.SelectMany(sheet => ((WorksheetPart)wbPart!.GetPartById(sheet.Id!))
            .DrawingsPart?.WorksheetDrawing?
            .Select(drawObject => drawObject?.OfType<Shape>()?
            .FirstOrDefault()?.InnerText) ?? []);

    return string.Join(",", cellsValue.Concat(objectsValue));
}
// 共通文字列テーブルを考慮した処理で取得します
private static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
    string value = cell.CellValue?.InnerText;

    if (cell.DataType is not null && cell.DataType.Value == CellValues.SharedString)
    {
        int sharedStringIndex = int.Parse(value);
        SharedStringItem item = document.WorkbookPart.SharedStringTablePart.SharedStringTable
                .Elements<SharedStringItem>().ElementAt(sharedStringIndex);
        return item?.Text?.InnerText;
    }
    return value;

}

共通文字列テーブル

エクセルVBAにように、ブック→シート→セルの順序でアクセスするのではなく、セルの共通文字列テーブルを考慮する必要がありました。
GetCellValue関数の部分
共有文字列テーブルを操作する

ワードの文字取得

private static string GetWordValue(string fileName)
{
    //すでに開いているwordファイルを開けるようにする
    var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    using var document = WordprocessingDocument.Open(fs, false);
    var documentValue = document.MainDocumentPart.Document.Body
            .Select(x => x.InnerText);

    return string.Join(",", documentValue);
}

ファイルで分岐する

public static string GetFileValue(string fileName)
{
    return fileName switch
    {
        var x when !File.Exists(x) => null,
        var x when Regex.IsMatch(x, @"^.*\.xls.$") => GetExcelValue(x),
        var x when Regex.IsMatch(x, @"^.*\.doc.$") => GetWordValue(x),
        _ => null
    };
}

古いファイル形式は対象外

.xls.docのような古いファイル形式はOpenXmlで読み込めません。
これは、その形式がXMLベースではないため。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?