下是一个简单的示例代码,用于使用 OpenXML 读取 Excel 文件中的数据:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main()
{
string filePath = "your_excel_file.xlsx";
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.FirstOrDefault();
if (worksheetPart != null)
{
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
foreach (Row row in sheetData.Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
string cellValue = GetCellValue(workbookPart, cell);
Console.Write(cellValue + "\t");
}
Console.WriteLine();
}
}
}
}
static string GetCellValue(WorkbookPart workbookPart, Cell cell)
{
string value = cell.CellValue?.InnerText;
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
SharedStringTablePart stringTablePart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
value = stringTablePart.SharedStringTable.ElementAt(int.Parse(value)).InnerText;
}
return value;
}
}
demo2
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
string filePath = @"C:\test.xlsx";
var result = new List<string>();
using (var document = SpreadsheetDocument.Open(filePath, false))
{
var workbookPart = document.WorkbookPart;
var sheets = workbookPart.Workbook.Sheets;
foreach (var sheet in sheets)
{
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
if (sheetData == null) continue;
foreach (var row in sheetData.Elements<Row>())
{
int rowNumber = row.RowIndex.Value;
foreach (var cell in row.Elements<Cell>())
{
string cellText = GetCellText(cell);
if (!string.IsNullOrEmpty(cellText))
{
string column = GetColumnLetter(cell.CellReference.Value);
result.Add($"Sheet: {sheet.Name}, 单元格: {column}{rowNumber}, 内容: {cellText}");
}
}
}
}
}
foreach (var line in result)
{
Console.WriteLine(line);
}
string GetCellText(Cell cell)
{
if (cell.InlineString != null)
{
return cell.InlineString.Text?.Text?.Trim();
}
if (cell.CellValue != null)
{
return cell.CellValue.Text?.Trim();
}
return null;
}
string GetColumnLetter(string cellReference)
{
int endIndex = cellReference.IndexOfAny("0123456789".ToCharArray());
return endIndex > 0 ? cellReference.Substring(0, endIndex) : "";
}
demo3
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
static string GetValue(Cell cell, SharedStringTablePart stringTablePart)
{
if (cell.ChildElements.Count == 0)
return "";
String value = cell.CellValue!.InnerText;
if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
value = stringTablePart.SharedStringTable
.ChildElements[Int32.Parse(value)]
.InnerText;
return value;
}
void GetExcelVlaue(string filePath)
{
SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false);
WorkbookPart? workbook = document.WorkbookPart;
IEnumerable<Sheet> sheets = document.WorkbookPart!.Workbook.Descendants<Sheet>();
if (sheets.Count() != 0)
{
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id!);
Worksheet worksheet = worksheetPart.Worksheet;
IEnumerable<Row> rows = worksheet.Descendants<Row>();
foreach (Row row in rows)
{
foreach (Cell cell in row)
{
string columnValue = GetValue(cell, workbook!.SharedStringTablePart!);
Console.Write(columnValue+" ");
}
Console.WriteLine();
}
}
}
GetExcelVlaue("字段替换表格.xlsx");
demo4完整代码
安装依赖
dotnet add package DocumentFormat.OpenXml
dotnet add package DocumentFormat.OpenXml.Vba # 用于 ActiveX 控件解析
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Vba;
using System.Collections.Generic;
using System.Linq;
public class ExcelControlTextExtractor
{
private readonly List<string> _results = new List<string>();
public List<string> ExtractControls(string filePath)
{
using (var document = SpreadsheetDocument.Open(filePath, false))
{
var workbookPart = document.WorkbookPart;
ExtractFormControls(workbookPart);
ExtractActiveXControls(workbookPart);
}
return _results;
}
#region ① フォームコントロール(Form Control)処理
private void ExtractFormControls(WorkbookPart workbookPart)
{
foreach (var sheet in workbookPart.Workbook.Sheets)
{
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var worksheet = worksheetPart.Worksheet;
string sheetName = sheet.Name ?? "Sheet";
if (worksheet.Controls != null)
{
foreach (var control in worksheet.Controls.Controls)
{
try
{
switch (control)
{
case Button button:
_results.Add($"【フォームボタン】{sheetName}: {button.Text}");
ExtractControlComments(control, sheetName);
break;
case CheckBox checkBox:
_results.Add($"【チェックボックス】{sheetName}: {checkBox.Caption}(状態:{checkBox.Checked})");
break;
case ComboBox comboBox:
string options = comboBox.List != null
? comboBox.List
: $"参照セル: {comboBox.ListFillRange}";
_results.Add($"【ドロップダウン】{sheetName}: {options}");
break;
case GroupBox groupBox:
_results.Add($"【グループボックス】{sheetName}(タイトル): {groupBox.Text}");
ExtractChildControls(groupBox, sheetName);
break;
case ListBox listBox:
_results.Add($"【リストボックス】{sheetName}: 項目数={listBox.Rows}");
break;
case OptionButton optionButton:
_results.Add($"【ラジオボタン】{sheetName}: {optionButton.Caption}(選択:{optionButton.Checked})");
break;
default:
_results.Add($"【未対応フォームコントロール】{sheetName}: {control.LocalName}");
break;
}
}
catch (System.Exception ex) { _results.Add($"エラー: {ex.Message}"); }
}
}
}
}
private void ExtractChildControls(GroupBox groupBox, string sheetName)
{
foreach (var childControl in groupBox.ChildControls)
{
if (childControl is Control control)
{
ExtractFormControls(new WorkbookPart { Workbook = new Workbook {
Sheets = new Sheets { new Sheet { Name = sheetName } }
} }, control, sheetName);
}
}
}
private void ExtractFormControls(WorkbookPart wbPart, Control control, string sheetName)
{
switch (control)
{
case Button btn: _results.Add($" 子ボタン: {btn.Text}"); break;
case CheckBox chk: _results.Add($" 子チェック: {chk.Caption}"); break;
}
}
#endregion
#region ② ActiveXコントロール(ActiveX Control)処理
private void ExtractActiveXControls(WorkbookPart workbookPart)
{
foreach (var olePart in workbookPart.GetPartsOfType<OleObjectPart>())
{
var oleObject = olePart.OleObject;
if (oleObject == null) continue;
string controlType = oleObject.ProgId?.Value;
var vbaControl = olePart.GetVbaControl();
string sheetName = GetSheetName(workbookPart, olePart);
try
{
if (vbaControl == null) return;
switch (controlType)
{
case "Forms.CommandButton.1":
string caption = vbaControl.GetProp("Caption");
_results.Add($"【ActiveXボタン】{sheetName}: {caption}");
ExtractActiveXComments(olePart, sheetName);
break;
case "Forms.TextBox.1":
string text = vbaControl.GetProp("Text");
_results.Add($"【テキストボックス】{sheetName}: {text}");
break;
case "Forms.ComboBox.1":
string items = vbaControl.GetProp("List");
_results.Add($"【ActiveXドロップダウン】{sheetName}: 選択肢={items}");
break;
case "Forms.CheckBox.1":
string state = vbaControl.GetProp("Value");
string label = vbaControl.GetProp("Caption");
_results.Add($"【ActiveXチェック】{sheetName}: {label}(状態:{state})");
break;
case "Forms.Label.1":
_results.Add($"【ラベル】{sheetName}: {vbaControl.GetProp("Caption")}");
break;
default:
_results.Add($"【未対応ActiveX】{sheetName}: {controlType}");
break;
}
}
catch { }
}
}
private void ExtractActiveXComments(OleObjectPart olePart, string sheetName)
{
var drawingPart = olePart.GetParentPartsOfType<DrawingPart>().FirstOrDefault();
if (drawingPart == null) return;
var commentList = drawingPart.Drawing.Descendants<CommentList>().FirstOrDefault();
if (commentList != null)
{
foreach (var comment in commentList.Elements<Comment>())
{
_results.Add($" コメント: {comment.Text?.Text}(ActiveX用)");
}
}
}
#endregion
#region ③ 共通ユーティリティメソッド
private void ExtractControlComments(OpenXmlElement control, string sheetName)
{
var commentList = control.Ancestors<CommentList>().FirstOrDefault();
if (commentList == null) return;
foreach (var comment in commentList.Elements<Comment>())
{
_results.Add($" コメント: {comment.Text?.Text}(フォーム用)");
}
}
private string GetSheetName(WorkbookPart workbookPart, OpenXmlPart part)
{
var relationship = workbookPart.GetIdOfPart(part);
return workbookPart.Workbook.Sheets
.Where(s => s.Id == relationship)
.Select(s => s.Name)
.FirstOrDefault() ?? "不明";
}
public static string GetProp(this VbaControl control, string propName)
{
return control.Properties?.Elements<VbaProperty>()
.Where(p => p.Name == propName)
.Select(p => p.StringValue)
.FirstOrDefault()?.Trim() ?? "未設定";
}
#endregion
public static void Main()
{
var extractor = new ExcelControlTextExtractor();
var results = extractor.ExtractControls(@"C:\test.xlsm");
System.IO.File.WriteAllLines(@"C:\result.txt", results);
foreach (var line in results) Console.WriteLine(line);
}
}