DocurainはExcelファイルをテンプレートとし、さらに描画するデータを与えて帳票やレポートを作成します。与えるデータフォーマットはJSONが一般的なのですが、CSVやTSVも利用可能です。
今回はCSVファイルを使った請求書作成について解説します。
CSVファイルについて
今回利用するCSVファイルは次のようになっています(抜粋です)。企業名、個人名、住所、郵便番号はダミーで生成したものになります。
#no,date,companyname,accountname,address,zipcode,tel,note,item,price,total,tax,totalPrice
1,2021/11/30,有限会社 渚,吉田 浩,岐阜県藤本市斉藤町鈴木3-9-7,215-9066,080-8054-8454,"いつもお世話になります。
2021年11月分の請求書になります。",製品1,4000,14500,1450,15950
1,2021/11/30,有限会社 渚,吉田 浩,岐阜県藤本市斉藤町鈴木3-9-7,215-9066,080-8054-8454,"いつもお世話になります。
2021年11月分の請求書になります。",製品2,6000,14500,1450,15950
:
3,2021/11/30,有限会社 木村,青田 香織,山形県加藤市吉田町加藤9-6-7,167-2711,090-2125-2506,お世話になります。よろしくお願いいたします。,アイテム1,1300,9000,900,9900
3,2021/11/30,有限会社 木村,青田 香織,山形県加藤市吉田町加藤9-6-7,167-2711,090-2125-2506,お世話になります。よろしくお願いいたします。,アイテム2,1000,9000,900,9900
3,2021/11/30,有限会社 木村,青田 香織,山形県加藤市吉田町加藤9-6-7,167-2711,090-2125-2506,お世話になります。よろしくお願いいたします。,アイテム3,6700,9000,900,9900b
ここで注意して欲しい点は以下になります。
- ヘッダー行を定義する場合には
#
を最初に記述する
- 帳票をまとめるユニークキー(今回はno)を用意する
- すべての明細行に帳票のヘッダー情報を記述する
ヘッダー行を定義する場合には #
を最初に記述する
たとえば次のようなCSVファイルがあったとします(#がないパターンです)。
no,date,name
1,2021-04-01,テスト 太郎
2,2021-05-01,テスト 花子
3,2021-06-01,テスト 次郎
これをDocurainのデータファイルとして適用した場合 $ROOT
は次のように送られてきます。
[
["no", "date", "name"],
["1", "2021-04-01", "テスト 太郎"],
["2", "2021-05-01", "テスト 花子"],
["3", "2021-06-01", "テスト 次郎"]
]
それに対して、最初に #
を付けた場合の $ROOT
は次のようになります。
[
{
"no": 1, "date": "2021-04-01", "name": "テスト 太郎",
},
{
"no": 2, "date": "2021-05-01", "name": "テスト 花子",
},
{
"no": 3, "date": "2021-06-01", "name": "テスト 次郎",
},
]
後者のヘッダーを設定した場合、 $ROOT[0].no
のようにアクセスできます。CSVにはヘッダーのような概念がないので、注意してください。
帳票をまとめるユニークキー(今回はno)を用意する
この後のテンプレート側の処理で紹介しますが、どこからどこまでが同じ帳票であるか区別できる必要があります。今回は no
という列を持たせて、そこで次の帳票になった時に数字を変更しています。
すべての明細行に帳票のヘッダー情報を記述する
CSVは多段構造は表現できません。そのため帳票ヘッダー、明細のように出力する際には、どちらの情報も一行の中に入れてしまうのがお勧めです。明細行の中に、ヘッダー情報も繰り返し入れてしまうことで、一部を取り出してヘッダー行情報として利用できます。つまり次のような形です。
#set($header = $ROOT[0])
テンプレートについて
今回はMicrosoft Officeで提供されている請求書テンプレートを利用します。
テンプレートの実装
まずA1セルにて、テンプレートで利用するデータの変数を定義し、さらに帳票ごとにグルーピングします。
#set($e = $ROOT)
#set($pages = $e.chunk('no'))
$e.chunk('no')
を実行すると、ある特定のカラム(今回はno)が同じデータは同じ配列グループになります。元データは $e は次のようになっていると考えてください。
[
{
"no": 1, "date": "2021-04-01", "name": "テスト 太郎",
},
{
"no": 1, "date": "2021-05-01", "name": "テスト 太郎",
},
{
"no": 2, "date": "2021-06-01", "name": "テスト 花子",
},
{
"no": 2, "date": "2021-07-01", "name": "テスト 花子",
},
{
"no": 2, "date": "2021-08-01", "name": "テスト 花子",
},
{
"no": 3, "date": "2021-09-01", "name": "テスト 次郎",
},
{
"no": 3, "date": "2021-10-01", "name": "テスト 次郎",
},
]
このデータに対して $e.chunk('no')
を実行すると、次のように変換されます。
[
[
{
"no": 1, "date": "2021-04-01", "name": "テスト 太郎",
},
{
"no": 1, "date": "2021-05-01", "name": "テスト 太郎",
}
],
[
{
"no": 2, "date": "2021-06-01", "name": "テスト 花子",
},
{
"no": 2, "date": "2021-07-01", "name": "テスト 花子",
},
{
"no": 2, "date": "2021-08-01", "name": "テスト 花子",
}
],
[
{
"no": 3, "date": "2021-09-01", "name": "テスト 次郎",
},
{
"no": 3, "date": "2021-10-01", "name": "テスト 次郎",
}
]
]
このようにグルーピングされれば、後はこのグループ毎に帳票を作成するだけです。
グループ毎の繰り返し
グルーピングできたら、そのグループ毎に処理を行います。つまり foreach を使います。$pageにはグルーピングされたCSV行が入ります。
#foreach($page in $pages)
// この中で帳票の処理
#end
つまり最初の $page
は以下のようになっていると考えてください。
[
{
"no": 1, "date": "2021-04-01", "name": "テスト 太郎",
},
{
"no": 1, "date": "2021-05-01", "name": "テスト 太郎",
}
]
ヘッダーの定義
帳票のヘッダーとして利用するデータを抽出します。1行目は必ず存在しますので、添え字として [0]
を利用します。
#set($h = $page[0])
ヘッダー行に関するデータ、たとえば会社名などは ${h.companyname}
で出力できます。
明細行の処理
明細行も繰り返しになりますので、foreachを使います。
#foreach($item in $page)
// この中で明細処理
#end
これで帳票のできあがりです。今回はデータの出力のみで、集計計算などは入れていません(CSVデータに元々入れています)。
まとめ
CSVはJSONとはデータ構造が異なるので、その扱いに多少の工夫がいります。しかし、JSONよりも使い慣れている人が多いので、業務システムとの連携ではCSVの方が活躍するかも知れません。
皆さんの帳票作りの参考にしてください。