Open XML SDK を利用してExcelシートの列の幅を設定する - C#

Open XML SDK を利用してExcelシートの列の幅を設定するコードを紹介します。

概要

こちらの記事ではOpen XML SDKを利用してExcelファイルのセルに値を設定して、出力するコードを紹介しました。 この記事では、セルに値を設定し、列の幅も列ごとに変更してExcelファイルを出力するコードを紹介します。

事前準備

プロジェクトを作成しOpen XML SDKをインストールします。インストール手順はこちらの記事を参照してください。

プログラム

Windows Formアプリケーションを作成します。

UI

下図のフォームを作成します。フォームにボタンが2つ配置されていますが、ボタンは1つのみ利用します。

コード

下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;


namespace ExcelApp
{
  public partial class Form_DataOutput : Form
  {
    List<DataItem> dataList = new List<DataItem>();
    class DataItem
    {
      public int id;
      public string name;
      public string code;
      public int price;

    }

    public Form_DataOutput()
    {
      InitializeComponent();
    }

    private void button2_Click(object sender, EventArgs e)
    {
      dataList.Clear();
      dataList.Add(new DataItem() { id = 1, name = "ぺんぎんクッキー", code = "PCD-001", price = 180 });
      dataList.Add(new DataItem() { id = 2, name = "あひるサブレ", code = "PCD-002", price = 120 });
      dataList.Add(new DataItem() { id = 3, name = "らくだキャラメル", code = "PCD-003", price = 40 });
      dataList.Add(new DataItem() { id = 4, name = "しろくまアイス", code = "PCA-001", price = 230 });
      dataList.Add(new DataItem() { id = 5, name = "だちょうカステラ", code = "PCD-004", price = 90 });

      //シート作成
      SpreadsheetDocument doc = SpreadsheetDocument.Create("c:\\data\\test-ex.xlsx", SpreadsheetDocumentType.Workbook);

      WorkbookPart wbpart = doc.AddWorkbookPart();
      wbpart.Workbook = new Workbook();
      WorksheetPart wspart = wbpart.AddNewPart<WorksheetPart>();
      wspart.Worksheet = new Worksheet(new SheetData());
      Sheets sheets = doc.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

      Sheet sheet = new Sheet();
      sheet.Id = doc.WorkbookPart.GetIdOfPart(wspart);
      sheet.SheetId = 1;
      sheet.Name = "商品";
      sheets.Append(sheet);


      //Column
      Columns lstColumns = wspart.Worksheet.GetFirstChild<Columns>();
      if (lstColumns == null) {
        lstColumns = new Columns();
        wspart.Worksheet.InsertAt(lstColumns, 0);
      }

      lstColumns.Append(new Column() { Min = 1, Max = 1, Width = 4, CustomWidth = true });
      lstColumns.Append(new Column() { Min = 2, Max = 2, Width = 25, CustomWidth = true });
      lstColumns.Append(new Column() { Min = 3, Max = 4, Width = 12, CustomWidth = true });


      //データ挿入
      Row row;
      UInt32Value row_index = 1;

      foreach (DataItem di in dataList) {
        row = new Row() { RowIndex = row_index };
        wspart.Worksheet.GetFirstChild<SheetData>().Append(row);

        Cell refCell = null;
        Cell newCell;

        newCell = new Cell() { CellReference = "A" + row_index.ToString() };
        newCell.CellValue = new CellValue(di.id.ToString());
        newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
        row.InsertAfter(newCell, refCell);
        refCell = newCell;
        //
        newCell = new Cell() { CellReference = "B" + row_index.ToString() };
        newCell.CellValue = new CellValue(di.name);
        newCell.DataType = new EnumValue<CellValues>(CellValues.String);
        row.InsertAfter(newCell, refCell);
        refCell = newCell;
        //
        newCell = new Cell() { CellReference = "C" + row_index.ToString() };
        newCell.CellValue = new CellValue(di.code);
        newCell.DataType = new EnumValue<CellValues>(CellValues.String);
        row.InsertAfter(newCell, refCell);
        refCell = newCell;
        //
        newCell = new Cell() { CellReference = "D" + row_index.ToString() };
        newCell.CellValue = new CellValue(di.price.ToString());
        newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
        row.InsertAfter(newCell, refCell);
        refCell = newCell;

        //row.InsertBefore(

        row_index++;
      }

      wbpart.Workbook.Save();

      doc.Close();
      MessageBox.Show("Excel Bookを作成しました。");
    }
  }
}

解説

シートの作成についてはこちらの記事を参照してください。
また、シートのセルへの値の設定はこちらの記事を参照してください。 今回のコードでは、先頭の行から順次、行ごとにセルを設定していく処理のコードになっています。

シートに書式を設定するコードが以下になります。
  //Column
  Columns lstColumns = wspart.Worksheet.GetFirstChild<Columns>();
  if (lstColumns == null) {
    lstColumns = new Columns();
    wspart.Worksheet.InsertAt(lstColumns, 0);
  }

  lstColumns.Append(new Column() { Min = 1, Max = 1, Width = 4, CustomWidth = true });
  lstColumns.Append(new Column() { Min = 2, Max = 2, Width = 25, CustomWidth = true });
  lstColumns.Append(new Column() { Min = 3, Max = 4, Width = 12, CustomWidth = true });

Worksheet オブジェクトのGetFirstChild() メソッドを呼び出し最初のColumnsオブジェクトを取得します。 Columnsオブジェクトが取得できなかった場合 (GetFirstChild メソッドの戻り値が null であった場合) は新しい Columns オブジェクトを作成します。 作成したColumnsオブジェクトをWorksheetオブジェクトに挿入します。
  Columns lstColumns = wspart.Worksheet.GetFirstChild<Columns>();
  if (lstColumns == null) {
    lstColumns = new Columns();
    wspart.Worksheet.InsertAt(lstColumns, 0);
  }

Columns オブジェクトに Column オブジェクトを追加します。ColumnsオブジェクトのAppendメソッドを呼び出しColumnオブジェクトを追加します。 Appendメソッドの引数に、追加するColumnオブジェクトを与えます。
ColumnsオブジェクトのMinが処理を開始する列、Maxが処理を終了する列、Widthに列の幅、CostomWidthは列幅を変更するためtrueを与えます。
下記のコードでは、1列目の幅を4に、2列目の幅を25に、3から4列目の幅をそれぞれ12に設定しています。
  lstColumns.Append(new Column() { Min = 1, Max = 1, Width = 4, CustomWidth = true });
  lstColumns.Append(new Column() { Min = 2, Max = 2, Width = 25, CustomWidth = true });
  lstColumns.Append(new Column() { Min = 3, Max = 4, Width = 12, CustomWidth = true });

実行結果

プロジェクトを実行します。下図のウィンドウが表示されます。


今回の処理を実装したボタンをクリックします。処理が完了するとメッセージボックスが表示されます。


出力先のディレクトリにExcelワークシートのファイルが作成されます。


Excelワークシートのファイルを開きます。下図の画面が表示されます。1列目(A列)の幅が狭く、2列目(B列)の幅が広く、 3,4列目(C,D列)の幅が標準より少し広く同じ幅で表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-01-08
作成日: 2020-10-14
iPentec all rights reserverd.