SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

クラウド時代にマッチする、ドキュメント生成・更新APIライブラリ「DioDocs(ディオドック)」(AD)

【Docker+.NETで作る見積書】DioDocs for Excelを使ったモダンな帳票アプリ開発

  • X ポスト
  • このエントリーをはてなブックマークに追加

帳票ページを作る

 前置きが長くなりましたが、ここから帳票の作成開始です。ここでは、「http/localhost:5000/Orders/ChouHyou?id=IDの値」というURLで呼び出されたとき、そのIDを持つ注文の見積書をPDFでダウンロードできるようにするようにしていきたいと思います。

DioDocs for Excelのインストール

 帳票の作成では、DioDocs for Excelを使います。第2回の手順と同様にして、NuGetパッケージマネージャを使って、インストールしておいてください。

帳票の基となるExcelテンプレートの準備

 まずは、帳票の基となるExcelテンプレートを準備します。グレープシティ社DioDocs for Excelでは、「既存のExcelファイルを読み込んで、そこに値を入れて出力する」ことができるため、このテンプレートは、Excelで自在に見栄えのよいものが作れます。ここでは、図7のように用意しました。見栄えのよいものが作れるという利点を活かし、見出しのところには色を付けてみました。

 図7に用意したテンプレートでは、「小計」「消費税」「合計」などをあらかじめExcelの計算式として設定しているという点に注目してください。「金銭型」の指定もしています。

 また小計は空欄のときに「¥0」と表示されないよう、カスタム書式で「¥#,##0_);[赤](¥#,##0);」を指定しています。なお、利用するフォントはDockerコンテナにすべて含めなければならない点に注意してください。

 前回説明したように、例えばAdobe社がオープンソースとして提供している「源ノ角ゴシック(source-han-sans)」や「源ノ明朝(source-han-serif)」などを使って作ります。これらの書体は、いくつかの「太さ」(ウェイト)のものが用意されているため、「御見積書」などの文字は太いウェイトのものを使うと、美しい見栄えにできます。

図7 Excelテンプレートを用意する
図7 Excelテンプレートを用意する

 こうして用意したExcelテンプレートをDockerコンテナのなかに置きます。ここでは、ExcelTemplateというフォルダを作り、そのなかに、chouhyou.xlsxというファイル名として置きました。そしてフォントも必要です。fontsフォルダのなかに、利用したフォント一式を入れました(図8)。

図8 テンプレートとフォントを入れる
図8 テンプレートとフォントを入れる

帳票を生成するプログラム

 以上で準備が整いました。帳票を作成するプログラムを作ります。Pages/Ordersフォルダに「ChouHyou.cshtml.cs」というファイルを作ります(リスト4)。また「ChouHyou.cshtml」というファイルも作ります(リスト5)。

[リスト4]Pages/Orders/ChouHyou.cshtml.cs

#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using System.Globalization;

// DioDocs for Excelの読み込み
using GrapeCity.Documents.Excel;
// モデルの読み込み
using exampleapp.Models;

namespace exampleapp.Pages.Orders
{
    public class ChouHyouModel : PageModel
    {
        private readonly MyAppContext _context;

        public ChouHyouModel(MyAppContext context)
        {
            _context = context;
        }

        [BindProperty]
        public exampleapp.Models.Order Order { get; set; }

        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            // 明細混みでデータベースから読み込む
            Order = await _context.Order.Include(c => c.Details)
                        .FirstOrDefaultAsync(m => m.OrderID == id);

            if (Order == null)
            {
                return NotFound();
            }

            // 帳票処理
            // 新規ワークブックの作成
            var workbook = new GrapeCity.Documents.Excel.Workbook();

            // テンプレートを開く
            workbook.Open("ExcelTemplate/chouhyou.xlsx");            

            // フォントとカルチャーの設定
            Workbook.FontsFolderPath = "fonts";
            workbook.Styles["標準"].Font.Name = "SourceHanSerif-Regular";
            workbook.Culture = CultureInfo.GetCultureInfo("ja-JP");

            // データの埋め込み
            IWorksheet worksheet = workbook.ActiveSheet;            
            // 見積日
            worksheet.Range["D2"].Value = DateTime.Today;
            // 取引先の会社名
            worksheet.Range["A4"].Value = Order.Company + " 御中";

            // 明細
            int row = 11;
            foreach (Detail detail in Order.Details) {
                worksheet.Cells[row, 0].Value = detail.ProductName;
                worksheet.Cells[row, 1].Value = detail.Quantity;
                worksheet.Cells[row, 2].Value = detail.UnitPrice;
                row = row + 1;
            }
            worksheet.Cells[row, 0].Value = "* 以下余白 *";

            // PDF化
            var stream = new MemoryStream();
            workbook.Save(stream, SaveFileFormat.Pdf);

            return File(stream.GetBuffer(), "application/pdf", "chouhyou.pdf");
        }
    }
}
[リスト5]Pages/Orders/ChouHyou.cshtml
@page
@model exampleapp.Pages.Orders.ChouHyouModel

 データベースのデータは、次のようにして読み込めます。明細も含めて読み込むため、Includeを指定しています。

// 明細混みでデータベースから読み込む
Order = await _context.Order.Include(c => c.Details)
              .FirstOrDefaultAsync(m => m.OrderID == id);

 こうしてデータベースから読み込んだOrderを帳票化します。

既存のExcelファイルの読み込み

 まずは、Excelワークブックを作り、用意しておいたテンプレートのExcelファイルを読み込みます。

// 新規ワークブックの作成
var workbook = new GrapeCity.Documents.Excel.Workbook();

// テンプレートを開く
workbook.Open("ExcelTemplate/chouhyou.xlsx");   

フォントとカルチャーの設定

 そして、フォントとカルチャーを設定します。フォントは文字化けしないようにするために必須なのは言うまでもありませんが、カルチャーも大事です。この設定を忘れると、日付が「年/月/日」ではなくて「月/日/年」のように表示されてしまいます。

// フォントとカルチャーの設定
Workbook.FontsFolderPath = "fonts";
workbook.Styles["標準"].Font.Name = "SourceHanSerif-Regular";
workbook.Culture = CultureInfo.GetCultureInfo("ja-JP");

値の埋め込み

 次に、値を埋め込んでいきます。まずは、ワークシートを取得します。

IWorksheet worksheet = workbook.ActiveSheet;

 そして値を埋め込みます。特定のセルに値を設定するには、次のように、Rangeプロパティを使えばよいでしょう。

// 見積日
worksheet.Range["D2"].Value = DateTime.Today;

 ループなどで回したいときは、Cellsプロパティを使って、「行」「列」の番号を指定するとよいでしょう。行・列は、どちらも0始まり(0オリジン)です。

// 明細
int row = 11;
foreach (Detail detail in Order.Details) {
    worksheet.Cells[row, 0].Value = detail.ProductName;
    worksheet.Cells[row, 1].Value = detail.Quantity;
    worksheet.Cells[row, 2].Value = detail.UnitPrice;
    row = row + 1;
}

PDFに変換して返す

 PDFに変換してダウンロードさせるには、いくつかの方法がありますが、MemoryStreamオブジェクトを作って、そこに書き出して、そのバッファを出力するのが簡単です。引数に指定している「application/pdf」はコンテンツタイプ「chouhou.pdf」は、ダウンロードするファイルに付ける既定のファイル名です。

// PDF化
var stream = new MemoryStream();
workbook.Save(stream, SaveFileFormat.Pdf);

return File(stream.GetBuffer(), "application/pdf", "chouhyou.pdf");

帳票ダウンロードへのリンクを貼る

 以上でプログラムは完成です。最後に、Orders/Index.cshtmlに、帳票ダウンロードへのリンクを貼ります。

<td>
    <a asp-page="./Edit" asp-route-id="@item.OrderID">Edit</a> |
    <a asp-page="./Details" asp-route-id="@item.OrderID">Details</a> |
    <a asp-page="./Delete" asp-route-id="@item.OrderID">Delete</a>
</td>

 もともとのIndex.cshtmlの部分に、ChouHyouへのリンクを加えるだけです。

<td>
    <a asp-page="./Edit" asp-route-id="@item.OrderID">Edit</a> |
    <a asp-page="./Details" asp-route-id="@item.OrderID">Details</a> |
    <a asp-page="./Delete" asp-route-id="@item.OrderID">Delete</a>
    <!-- 帳票へのリンクを追加 -->
    <a asp-page="./ChouHyou" asp-route-id="@item.OrderID">帳票ダウンロード</a>
</td>

 これで完成です。実行してhttp://localhost:5000/Orders/にアクセスすると「帳票ダウンロード」というリンクが表示されており、このリンクをクリックすると、その帳票がPDF形式でダウンロードできます(図9)。ダウンロードできる帳票は、図10の通りです。

図9 [帳票ダウンロード]をクリックすると帳票をダウンロードできる
図9 [帳票ダウンロード]をクリックすると帳票をダウンロードできる
図10 ダウンロード後の帳票
図10 ダウンロード後の帳票

まとめ

 本連載では、Docker環境でDioDocs for Excelを使う方法を説明してきました。Dockerをそのまま開発に使うと少しややこしいのですが、Remote - Containers拡張を使えばそうした複雑さがなく開発できます。

 Dockerは、自分のホストとは隔離された環境なので、「フォント」や「日本語設定」が引き継がれません。なのでフォントとカルチャーの設定し忘れには注意しましょう。

 今回お見せしたように、DioDocs for ExcelはExcelでテンプレートを作っておき、そこに値を埋め込んで出力することができるため、見栄えのよいデザインの帳票が作りやすいのが魅力です。罫線や飾り、グラフィックなどを埋め込むことが容易なため、帳票に限らず商品ラベルや宛名ラベルなど、さまざまな「差し込み印刷」を実現したい場面でも重宝すると思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
クラウド時代にマッチする、ドキュメント生成・更新APIライブラリ「DioDocs(ディオドック)」連載記事一覧

もっと読む

この記事の著者

大澤 文孝(オオサワ フミタカ)

テクニカル・ライター、プログラマ/システムエンジニア。情報セキュリティスペシャリスト、ネットワークスペシャリスト。入門書からプログラミングの専門書まで幅広く執筆。   主な著作として、「Amazon Web Services 基礎からのネットワーク&サーバー構築(共著)」(...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/15732 2022/04/06 12:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング