Symfoware

Symfowareについての考察blog

OpenXML + C#のプログラムでExcelの行の高さ、列の幅を指定する

OpenXMLを使用して、C#のプログラムからExcelファイルの出力を試してみました。

OpenXMLを使用してExcelファイルをC#のプログラムから出力する
http://symfoware.blog68.fc2.com/blog-entry-1137.html


今回は、出力する際に行の高さや列の幅を指定してみます。




行の高さサンプル



行の高さの指定には2通りの方法があるようです。

まず、シート全体の行の高さのデフォルト値を指定する「DefaultRowHeight」と、
それぞれの行の高さを指定する「Height」です。

サンプルはこのようになります。


  1. using System;
  2. using DocumentFormat.OpenXml;
  3. using DocumentFormat.OpenXml.Packaging;
  4. using DocumentFormat.OpenXml.Spreadsheet;
  5. public class Sample {
  6.     
  7.     public static void Main(string[] args) {
  8.         
  9.         // 新しいxlsxドキュメントを作成
  10.         SpreadsheetDocument document = SpreadsheetDocument.Create("Test.xlsx", SpreadsheetDocumentType.Workbook, true);
  11.         
  12.         // ドキュメントのワークブックパートに、ワークブックを設定
  13.         WorkbookPart wbpart = document.AddWorkbookPart();
  14.         wbpart.Workbook = new Workbook();
  15.         
  16.         // ワークブックパートに、ワークシートパートを設定
  17.         WorksheetPart wspart = wbpart.AddNewPart<WorksheetPart>();
  18.         SheetData sheetData = new SheetData();
  19.         wspart.Worksheet = new Worksheet(sheetData);
  20.         
  21.         // 1.シート全体の行の高さのデフォルト指定
  22.         wspart.Worksheet.SheetFormatProperties = new SheetFormatProperties();
  23.         wspart.Worksheet.SheetFormatProperties.DefaultRowHeight = 50;
  24.         wspart.Worksheet.SheetFormatProperties.CustomHeight = true;
  25.         
  26.         // ワークブックにシートを設定
  27.         Sheets sheets = wbpart.Workbook.
  28.                 AppendChild<Sheets>(new Sheets());
  29.         
  30.         // シートを1つ追加
  31.         Sheet sheet = new Sheet() { Id = wbpart.GetIdOfPart(wspart), SheetId = 1, Name = "Sheet1" };
  32.         sheets.Append(sheet);
  33.         
  34.         
  35.         // ここまでがお決まりの処理
  36.         // Sheetではなく、SheetDataにデータを設定していく
  37.         
  38.         // Cell単独では存在できない模様
  39.         // Rowオブジェクトを作成し、そこにCellデータを追加していく。
  40.         Row row = new Row();
  41.         
  42.         //2.個別に行の高さ指定
  43.         row.Height = 20;
  44.         row.CustomHeight = true;
  45.         
  46.         Cell cell = new Cell();
  47.         cell.DataType = CellValues.String;
  48.         cell.CellReference = "A1";
  49.         cell.CellValue = new CellValue("A1のセル");
  50.         
  51.         row.Append(cell);
  52.         
  53.         // 最後にRowをSheetDataに追加
  54.         sheetData.Append(row);
  55.         
  56.         // ファイルを保存
  57.         document.Close();
  58.     }
  59. }




ここでハマったのですが、LibreOfficeとMSOfficeで表示のされかたが異なります。


LibreOffice

224_01.png


MSOffice 2013

224_02.png


LibreOfficeは「DefaultRowHeight」のみが有効となり、MSOffice 2013は狙い通りの表示になります。
プログラムの書き方に誤りがあるのかも。原因はわかりませんでした。






列の幅指定



列の幅指定も、行の高さ指定と同様にシート全体のデフォルト値指定と、
個別指定が行えます。


  1. using System;
  2. using DocumentFormat.OpenXml;
  3. using DocumentFormat.OpenXml.Packaging;
  4. using DocumentFormat.OpenXml.Spreadsheet;
  5. public class Sample {
  6.     
  7.     public static void Main(string[] args) {
  8.         
  9.         // 新しいxlsxドキュメントを作成
  10.         SpreadsheetDocument document = SpreadsheetDocument.Create("Test.xlsx", SpreadsheetDocumentType.Workbook, true);
  11.         
  12.         // ドキュメントのワークブックパートに、ワークブックを設定
  13.         WorkbookPart wbpart = document.AddWorkbookPart();
  14.         wbpart.Workbook = new Workbook();
  15.         
  16.         // ワークブックパートに、ワークシートパートを設定
  17.         WorksheetPart wspart = wbpart.AddNewPart<WorksheetPart>();
  18.         SheetData sheetData = new SheetData();
  19.         wspart.Worksheet = new Worksheet();
  20.         
  21.         // 1.シート全体の列の幅のデフォルト指定
  22.         wspart.Worksheet.SheetFormatProperties = new SheetFormatProperties();
  23.         wspart.Worksheet.SheetFormatProperties.DefaultRowHeight = 0;
  24.         wspart.Worksheet.SheetFormatProperties.DefaultColumnWidth = 5;
  25.         
  26.         // ワークブックにシートを設定
  27.         Sheets sheets = wbpart.Workbook.
  28.                 AppendChild<Sheets>(new Sheets());
  29.         
  30.         // シートを1つ追加
  31.         Sheet sheet = new Sheet() { Id = wbpart.GetIdOfPart(wspart), SheetId = 1, Name = "Sheet1" };
  32.         sheets.Append(sheet);
  33.         
  34.         
  35.         // ここまでがお決まりの処理
  36.         // Sheetではなく、SheetDataにデータを設定していく
  37.         
  38.         // 2.個別に列の幅を指定
  39.         Columns columns = new Columns();
  40.         Column column = new Column();
  41.         column.Min = 1;
  42.         column.Max = 1;
  43.         column.Width = 20;
  44.         column.CustomWidth = true;
  45.         
  46.         columns.Append(column);
  47.         wspart.Worksheet.Append(columns);
  48.         
  49.         // Cell単独では存在できない模様
  50.         // Rowオブジェクトを作成し、そこにCellデータを追加していく。
  51.         Row row = new Row();
  52.         
  53.         Cell cell = new Cell();
  54.         cell.DataType = CellValues.String;
  55.         cell.CellReference = "A1";
  56.         cell.CellValue = new CellValue("A1のセル");
  57.         
  58.         row.Append(cell);
  59.         
  60.         // 最後にRowをSheetDataに追加
  61.         sheetData.Append(row);
  62.         
  63.         // ここでWorksheetにデータを追加しないとファイルが壊れる
  64.         wspart.Worksheet.Append(sheetData);
  65.         
  66.         // ファイルを保存
  67.         document.Close();
  68.     }
  69. }




一見、「DefaultRowHeight = 0;」の指定は不要に思えますが、
これがないとMSOfficeでXMLが壊れていると表示され、ファイルが開けません。

こんなエラーが表示されます。

224_03.png

ここが参考になりました。
Setting Excel spreadsheet column properties issue
http://stackoverflow.com/questions/13120146/setting-excel-spreadsheet-column-properties-issue

DefaultRowHeightは必須のプロパティのようです。



また、Worksheet.Appendは、
・Columns
・SheetData
の順番に行わないと、これまたファイルが壊れます。(MSOfficeだけ)

最初、LibreOfficeでファイルができてるか確認していたので、
MSOfficeでファイルが開けなかった時泣きそうになりました。

生成されるファイルの内容はこんな感じです。


LibreOffice

224_04.png


MSOffice 2013

224_05.png



LibreOfficeだけじゃなくて、MSOffice 2013でも表示のテストしたほうが良いです。
あと、Appendのタイミングによってはファイルが壊れます。
実行時にエラーは発生しませんし、プログラム的にも正しく見えるので
解決するのが厄介です。






【参考URL】
Advanced styling in Excel Open XML
http://polymathprogrammer.com/2009/12/21/advanced-styling-in-excel-open-xml/

Custom column widths in Excel Open XML
http://polymathprogrammer.com/2010/01/11/custom-column-widths-in-excel-open-xml/

Setting Excel spreadsheet column properties issue
http://stackoverflow.com/questions/13120146/setting-excel-spreadsheet-column-properties-issue

SheetFormatProperties Properties
http://msdn.microsoft.com/ja-jp/library/documentformat.openxml.spreadsheet.sheetformatproperties_properties(v=office.14).aspx
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2013/10/05(土) 23:08:19|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<OpenXML + C#のプログラムでフォントの指定を行う | ホーム | OpenXMLを使用してExcelファイルをC#のプログラムから出力する>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1138-8519996e
この記事にトラックバックする(FC2ブログユーザー)