Open XML SDK 備忘録

おもにExcelファイル (.xlsx) を扱います。

P-SPACE
就学奨励費システム

マイナンバー対応 特別支援教育 就学奨励費 支給業務支援システム

詳細...

P-SPACE
就学奨励費ソフトウェア

特別支援教育 就学奨励費 支給業務支援ソフトウェア

詳細...

開発室
(備忘録そのほか)

システム開発にまつわる(かもしれない)調査・実験結果など

詳細...

セルの書式設定 - 文字の配置

今回はセル内での文字の配置を操作します。

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace OpenXMLSDK_Sample5 {
    class Program {
        static void Main(string[] args) {
            const string FILE = @"C:\Users\Public\Documents\openxmlsdk12.xlsx";
            const string SHEET_NAME = "Sheet1";

            using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(FILE, true)) {
                WorkbookPart bookPart = excelDoc.WorkbookPart;

                int sheet_index = GetWorksheetIndex(bookPart, SHEET_NAME);
                WorksheetPart sheet_part = GetWorksheetPart(bookPart, sheet_index);

                SetCellAlignment(bookPart, GetCell(sheet_part, "A1"), HorizontalAlignmentValues.Left, VerticalAlignmentValues.Top);
                SetCellAlignment(bookPart, GetCell(sheet_part, "B1"), HorizontalAlignmentValues.Center, VerticalAlignmentValues.Top);
                SetCellAlignment(bookPart, GetCell(sheet_part, "C1"), HorizontalAlignmentValues.Right, VerticalAlignmentValues.Top);

                SetCellAlignment(bookPart, GetCell(sheet_part, "A2"), HorizontalAlignmentValues.Left, VerticalAlignmentValues.Center);
                SetCellAlignment(bookPart, GetCell(sheet_part, "B2"), HorizontalAlignmentValues.Center, VerticalAlignmentValues.Center);
                SetCellAlignment(bookPart, GetCell(sheet_part, "C2"), HorizontalAlignmentValues.Right, VerticalAlignmentValues.Center);

                SetCellAlignment(bookPart, GetCell(sheet_part, "A3"), HorizontalAlignmentValues.Left, VerticalAlignmentValues.Bottom);
                SetCellAlignment(bookPart, GetCell(sheet_part, "B3"), HorizontalAlignmentValues.Center, VerticalAlignmentValues.Bottom);
                SetCellAlignment(bookPart, GetCell(sheet_part, "C3"), HorizontalAlignmentValues.Right, VerticalAlignmentValues.Bottom);

                //保存
                sheet_part.Worksheet.Save();
            }

            //ファイルを開く
            System.Diagnostics.Process.Start(FILE);
        }

        private static void SetCellAlignment(WorkbookPart bookPart, Cell cell, HorizontalAlignmentValues h_align, VerticalAlignmentValues v_align) {
            if(cell == null || bookPart == null) {
                return;
            }

            IEnumerable<CellFormat> cell_formats = bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Elements<CellFormat>();
            if (cell.StyleIndex != null) {
                CellFormat current_xf = cell_formats.ElementAt(Convert.ToInt32(cell.StyleIndex.Value));

                //同じ属性をもち、かつ指定されたalignと同じ設定をもつCellFormatを探す
                CellFormat format_to = cell_formats.FirstOrDefault(
                    r => r.GetAttributes().SequenceEqual(current_xf.GetAttributes())
                    && r.Alignment != null
                    && r.Alignment.Horizontal != null && r.Alignment.Horizontal.Value == h_align
                    && r.Alignment.Vertical != null && r.Alignment.Vertical.Value == v_align);
                if (format_to == null) {
                    format_to = current_xf.Clone() as CellFormat;
                    if (format_to.Alignment == null) {
                        format_to.Alignment = new Alignment();
                    }
                    if(format_to.Alignment.Horizontal == null) {
                        format_to.Alignment.Horizontal = new EnumValue<HorizontalAlignmentValues>();
                    }
                    format_to.Alignment.Horizontal.Value = h_align;

                    if (format_to.Alignment.Vertical == null) {
                        format_to.Alignment.Vertical = new EnumValue<VerticalAlignmentValues>();
                    }
                    format_to.Alignment.Vertical.Value = v_align;
                    
                    bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Append(format_to);
                    bookPart.WorkbookStylesPart.Stylesheet.Save();
                    cell.StyleIndex = new UInt32Value((uint)cell_formats.Count() - 1);
                }else {
                    cell.StyleIndex = new UInt32Value((uint)(cell_formats.ToList().IndexOf(format_to)));
                }
            } else {
                CellFormat format_to = new CellFormat();
                format_to.Alignment = new Alignment();

                format_to.Alignment.Horizontal = new EnumValue<HorizontalAlignmentValues>();
                format_to.Alignment.Horizontal.Value = h_align;

                format_to.Alignment.Vertical = new EnumValue<VerticalAlignmentValues>();                
                format_to.Alignment.Vertical.Value = v_align;

                bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Append(format_to);
                bookPart.WorkbookStylesPart.Stylesheet.Save();
                cell.StyleIndex = new UInt32Value((uint)cell_formats.Count() - 1);
            }
        }
        // 以下省略
    }
}

 「以下省略」とした部分は前回「セルの書式設定 - 表示形式」のコードをご覧ください。

セル内の配置を決定するにあたっては、まずはそのセルになんらかの書式設定がされているかどうかを確認します。

当該セルに書式設定がされていない(s属性の指定がない)ならば、あらたにCellFormatを作成して、そのCellFormatに文字の配置を指定します。(上記コードの78行目~89行目)
しかし当該セルに書式が設定されている場合は、その書式を生かしつつ、セル内の文字の配置のみを変更する必要があります。

前回にも少し触れましたが、「当該セルのs属性からそのセルのCellFormatを特定し、さらにそのセル内の文字の配置を変更する」と、
当該セルと同じCellFormatを参照している別のセルが存在する場合には、それらセルについてもセル内の文字の配置が変更されてしまいます。

そこで当該セルに書式が設定されている場合は、まず初めにそのセルに適用されるCellFormatを特定し、そのCellFormatのクローンを作成します。
そのクローンについて文字の配置を指定したのちに、当該セルのs属性をそのクローンを指し示すように変更します。

上記のコードではクローンを作成する前に、所望するCellFormatが既に存在していないかどうかを調べます。(51行目~55行目)
もし所望するCellFormat ( 当該セルの文字配置「以外」の書式設定が当該セルの書式設定と同一であり、かつ文字配置が設定したい文字配置と同一となっているもの)が見つかった場合、
当該セルのs属性に見つかったCellFormatのインデックスを割り振ります。(75行目)