フォントとロケールの罠
このようにExcelファイルの作成は、すぐにできます。この簡単さがゆえに、DioDocs for Excelの便利さを感じるのですが、実は、ちょっと問題があります。
PDFに書き出す
DioDocs for Excelは、PDFとして書き出すこともできます。これはとても簡単で、Saveメソッドのオプションを変えるだけです。次のように「SaveFileFormat.Pdf」を指定すれば、PDFとして出力されます。
// PDFとして保存 workbook.Save("example.pdf", SaveFileFormat.Pdf);
しかし生成されたPDFを開くとわかりますが、実際には、日本語がまったく表示されません(図5)。これは、日本語フォントがコンテナにインストールされていないのが理由です。
フォントをインストールする
こうした「フォントがない」という状況は、実行環境としてWindowsしか想定しておらず、LinuxやDockerコンテナを想定していない開発では、よく起きます。
この問題を解決するには、コンテナのなかにフォントをインストールします。ただしもちろん、ライセンスの関係から、Windowsにインストールされているフォントをそのまま使うことはできません。
そこでライセンス上、問題がないオープンソースのフォントなどを用います。ここでは、アドビ社がオープンソースとして提供している「源ノ角ゴシック(source-han-sans)」や「源ノ明朝(source-han-serif)」を使うことにします。
いくつかのファイル形式がありますが、ここでは「OTF形式」を使います。GitHubのディレクトリのOTF/Japaneseフォルダに、文字の太さ(フォントのウェイト)が違うファイルがあるので、好みのものを選びます。ここではふつうの太さの「SourceHanSans-Regular.otf」と「SourceHanSerif-Regular.otf」をダウンロードします。
こうしてダウンロードしたOTF形式ファイルを、プロジェクトフォルダに適当なディレクトリに配置します。ここではfontsディレクトリに配置しました(図6)。
DioDocs for Excelでフォントを指定する
これでフォントの準備ができました。次にプログラムを修正して、このフォントを使って描画します。リスト1に対して、次の2点を修正します。
(1)フォントディレクトリの設定
DioDocs for Excelでは、WorkbookクラスのFontsFolderPathプロパティに、フォントの場所を設定します。図13のようにfontsディレクトリに設定したのであれば、次の文を追加します。
Workbook.FontsFolderPath = "fonts";
(2)標準スタイルのフォントを変更する
フォントを指定しない場合、標準スタイルのフォントが使われます。そこで標準スタイルのフォントを変更します。
workbook.Styles["標準"].Font.Name = "使いたいフォント名";
問題は「使いたいフォント名が何か」という点ですが、Adobe Fontsの場合は、SourceHanSansReadMe.pdfおよびSourceHanSerifReadMe.pdfに書かれていて、ファイル名と同じく「SourceHanSans-Regular」および「SourceHanSerif-Regular」です。ですから、源ノ角ゴシック(source-han-sans)なら、
workbook.Styles["標準"].Font.Name = "SourceHanSans-Regular";
源ノ明朝(source-han-serif)なら、
workbook.Styles["標準"].Font.Name = "SourceHanSerif-Regular";
このようにします(太さがRegularではない場合は、それに合わせてください)。
標準のフォントは列幅の計算に使われる
DioDocs for Excelでは、セルごとにフォントを設定できますが、その場合でも、標準スタイルのフォントは必ず設定するようにしてください。標準スタイルのフォントは、列幅の計算に使われるからです。標準スタイルのフォントが存在しない場合、PDFに出力したときに、列幅が正しく表示されないことがあります。
LinuxにてPDF出力時に列幅の計算に使用するフォントが実行環境にない場合、列幅が正しく出力されない – GrapeCity ナレッジベース (zendesk.com)
フォント名を知る
フォントのファイルから、フォント名を知りたいなら、内部構造を確認しなければなりません。それには、適当なOpenTypeフォントを扱えるツールを使うとよいでしょう。例えば、FontForgeというフォントエディタソフトを使ってOTF形式ファイルを開き、フォント情報を確認すると、そのフォント名がわかります(図7)。
カルチャの問題
これでフォントの問題は解決するのですが、もう1つ、DioDocs for Excelを使ううえでは、カルチャを日本語にしないと、列幅が狭くなるという問題があります。
Azure上でPDF出力すると列幅が狭くなりページ余白が大きくなる – GrapeCity ナレッジベース (zendesk.com)
この問題は、カルチャを日本に設定することで解決できます。
workbook.Culture = CultureInfo.GetCultureInfo("ja-JP");
タイムゾーンの問題
カルチャと並んでもう1つ、Dockerコンテナ環境では、「タイムゾーン」の問題が生じることがあります。「時間が9時間ズレている」という現象が発生したときは、プログラムのなかで明示的に、タイムゾーンの変換をしましょう。
// 現在日時を取得 DateTime now = DateTime.Now; // Asia/Tokyoタイムゾーンに変換 TimeZoneInfo jst = TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo"); DateTime now_jst = TimeZoneInfo.ConvertTime(now, jst); Console.WriteLine(now_jst.ToString("yyyy/MM/dd HH:mm:ss"));
まとめ
以上の修正をした最終的なプログラムを、リスト2に示します。dotnet runで実行して生成したPDFファイルを見ると、今度は、正しくPDFが表示されていることがわかります(図8)。
using GrapeCity.Documents.Excel; using System.Globalization; // ワークブックの初期化 Workbook workbook = new Workbook(); // フォントの設定 Workbook.FontsFolderPath = "fonts"; workbook.Styles["標準"].Font.Name = "SourceHanSans-Regular"; // カルチャの設定 workbook.Culture = CultureInfo.GetCultureInfo("ja-JP"); // アクティブなワークシートの取得 IWorksheet worksheet = workbook.ActiveSheet; // 書き込むダミーのデータ object[,] data = new object[,]{ {"氏名", "電話番号", "メールアドレス", "郵便番号", "都道府県", "住所"}, {"大川仁美", "055425366", "hitomi38579@itihvkjd.hlkpt.lm", "406-0854", "山梨県", "笛吹市境川町寺尾3-18-15"}, {"菅井礼子", "0744610199", "reikosugai@siadwn.fwr", "639-2245", "奈良県", "御所市今住3-8-16"}, {"福地浩之", "0596008348", "hiroyuki0893@cnous.xb.gwe", "511-0065", "三重県", "桑名市大央町3-12-3"}, {"芦田重樹", "0583477675", "iashida@hpebuwjuf.gy", "501-0411", "岐阜県", "本巣市上高屋4-2-18"}, {"高岡宏寿", "0520974210", "itakaoka@lukbsilq.ae", "441-8021", "愛知県", "豊橋市白河町3-17"} }; // データを設定する worksheet.Range["A1:F6"].Value = data; // PDFとして保存 workbook.Save("example.pdf", SaveFileFormat.Pdf);
ここまで説明してきたように、コンテナのなかは、フォントがインストールされているとは限りませんし、カルチャとして日本が設定されているとも限りません。ですから、普段、あまり気にしていないような、既定の環境を前提とした作り方では、うまくいかないことがあるので注意してください。ここで紹介した以外にもグレープシティ社のナレッジベースにDocker関連のTipsなどの情報があります。併せてこちらも参照してみてください。
今回は、簡単なコンソールアプリを作りながら、DioDocs for Excelの基本的な使い方を説明しました。次回は、今回説明した内容を使って、ASP.NETでありがちな帳票Webアプリケーションを、どのように構築すればよいのかを説明します。