Excelのセルに付いてる、メモというかコメントというか、アレを取得します。(Excel上の名称は「メモ」なのに、OpenXMLのクラス名はCommentなんだもん)
xlsxファイルの中を見てわかったのが、セル情報にメモが付属してるのでは無く、メモはシート毎に”comments*.xml”ファイルにコメントがかたまって収納されてる。なので取得がちょっと面倒。
(ちなみに、*はシート番号と一緒で、シートの順番を入れ替えると*の数も入れ替わる。おもろ)
サンプル(呼び出し側)
private void button1_Click(object sender, EventArgs e)
{
//実行ファイルのパス上にあるExcelファイル
string path = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "sample.xlsx");
//xlsxファイルを読み出す
var xlsx = ExcelWork.Open(path);
//シートを選択
xlsx.SelectSheet("Sheet1");
//"A1"セルにあるメモを取得
string memo = xlsx.GetMemo("A1");
//表示
MessageBox.Show(memo);
//閉じる
xlsx.Close();
}
サンプル(処理側:ExcelWork)
comment.OuterXmlでマークアップ?を取得してref=の部分を抜き取るという意味不明なことをやってるんだけど、もっと良い方法きっとあるよねきっと(汗 ・・・動きゃイイのさ!(ヤケ
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
class ExcelWork
{
private ExcelWork() { }
public void Dispose() => _document?.Dispose();
//Excel操作用(多いなぁ)
private SpreadsheetDocument _document;
private WorkbookPart _workbookPart;
private WorksheetPart _worksheetPart;
private Sheets _sheets;
private SheetData _sheetData;
// 既存のエクセルファイルをオープンする
public static ExcelWork Open(string filePath)
{
var obj = new ExcelWork();
obj._document = SpreadsheetDocument.Open(filePath, false);
obj._workbookPart = obj._document.WorkbookPart;
obj._sheets = obj._workbookPart.Workbook.GetFirstChild<Sheets>();
return obj;
}
//シートを選択
public void SelectSheet(string sheetName)
{
// workbookから指定したシートを見つける
var theSheet = _workbookPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
throw new ArgumentException("sheetName");
// WorkSheetPartを取り出す。これが以降の操作で必要
_worksheetPart = (WorksheetPart)_workbookPart.GetPartById(theSheet.Id);
// SheetDataを見つける
var worksheet = _worksheetPart.Worksheet;
_sheetData = worksheet.GetFirstChild<SheetData>();
}
//エクセルファイルを閉じる
public void Close()
{
_document.Close();
}
//指定セルのメモを取得
public string GetMemo(string cellPos)
{
//戻り値
string value = string.Empty;
//シートに関連した"comments?.xml"を調べる
foreach (WorksheetCommentsPart commentsPart in _worksheetPart.GetPartsOfType<WorksheetCommentsPart>())
{
foreach (Comment comment in commentsPart.Comments.CommentList)
{
//comment.OuterXmlでマークアップを取得し、ref=を確認
//(ref=にメモを表示するセルの場所が書かれている)
//しかし、もっと簡単に取得できないのかな
Match matche = Regex.Match(comment.OuterXml, "ref=\".+?\""); //最初に見つけた ref="~" を抽出
//余計な物を取り除く
string memoPos = matche.Value.Replace("\"", "");
memoPos = memoPos.Replace("ref=", "");
//目的のセルと同じ位置?
if (cellPos == memoPos)
{
value = comment.InnerText;
break;
}
}
}
return value;
}
}
コメント