.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ベースではないため。