PowerShellとLibreOffice Drawで請求書作成


LibreOffice AdventCalendar 2018 25日目

請求書を作ります。
請求書は業務システムでは最も一般的な帳票です。

一番の難関はページングです。

以下の条件で作ります。

  1. 6行明細の請求書に9行の売上。
  2. 請求書は2枚出力。
  3. 2枚目の最後の行には請求合計を出力

ソースは下記のGitHubにあります。

invoice - GitHub

環境

  • Windows10 Pro
    • PowerShell
  • LibreOffice Draw
    • Flat ODT(fodg)

作成開始

では作成していきます。

Templateを作成

  1. LibreOffice Drawで下記のようなTemplateを作ります
    • 用紙サイズはA4縦 -
  2. Flat XML ODF 図形描画(.fodg)で保存します

Dataを作成

  1. data.csvを作成
  2. headerは salesno,customer,supplier,item,subtotal
  3. 売上の内容をゴリゴリ書いていきます。

下記な感じになります。

salesno customer supplier item subtotal
1 You Amazon Nintendo Switch1 100
1 You Amazon Nintendo Switch2 200
1 You Amazon Nintendo Switch3 300
1 You Amazon Nintendo Switch4 400
1 You Amazon Nintendo Switch5 500
1 You Amazon Nintendo Switch6 600
1 You Amazon Nintendo Switch7 700
1 You Amazon Nintendo Switch8 800
1 You Amazon Nintendo Switch9 900

帳票作成シェル

makeinvoice.ps1 を作成します。
詳しくはソースを見て下さい。
ざっくりした説明をすると

  1. dataを読込
  2. templateを読込
  3. templateの{salesno}等を該当するデータに書換
  4. 6行目になったら請求書を出力
  5. 以下繰り返し
  6. 最後のあまりを請求書に出力
  7. 最後の請求書に合計を出力

となります。

makeinvoice.ps1
# load data
$data=Import-Csv -Path .\data.csv -Encoding UTF8

# load template
$temp=Get-Content .\invoice.fodg -Encoding UTF8

# cnt row in report
$i=1
# reportrows
$rprow=6
# total row count
$rc=0
# page
$p=0

# total page
$tp=$data.Count/$rprow
$tp=[Math]::Ceiling($tp)

# calcurate total
$sum=$data | Measure-Object 'subtotal' -sum

foreach($d in $data){     

    # merge template
    $temp=$temp -replace '{salesno}',$d.salesno
    $temp=$temp -replace '{customer}',$d.customer
    $temp=$temp -replace '{supplier}',$d.supplier
    $temp=$temp -replace "{item$i}",$d.item
    $temp=$temp -replace "{subtotal$i}",$d.subtotal

    # rowcount
    $rc=$rc+1

    # report end write build report
    if($i%$rprow -eq 0){
        # Write-Output "行"$rc
        # Write-Output "data数"$data.Count

        # Page Count
        $p=$p+1

        # write total
        if($rc -eq $data.Count){
            $temp=$temp -replace '{total}',$sum.Sum
        }

        # add Page No
        $temp=$temp -replace '{page}',"$p"
        # add Total Page
        $temp=$temp -replace '{total page}',"$tp"
        # delete {}
        $temp=$temp -replace "{(.*)}",""

        # output name 
        $date=Get-Date -Format yyyyMMddhhmmss
        $file="output\"+$date+$p

        # output newfile
        $temp | out-file -FilePath $file'.fodg' -Encoding utf8

        $i=$i-$rprow

        # load template
        $temp=Get-Content .\invoice.fodg -Encoding UTF8
    }

    # report in row
    $i=$i+1    
}

# output remainder data to report
if($data.Count%$rprow -ne 0){
    $p=$p+1
    $file="output\"+$date+$p

    # write total
    $temp=$temp -replace '{total}',$sum.Sum
    $temp=$temp -replace '{page}',"$p"
    $temp=$temp -replace '{total page}',"$tp"

    # delete {}
    $temp=$temp -replace "{(.*)}","" 

    #output report
    $temp | out-file -FilePath $file'.fodg' -Encoding utf8

}

印刷

print.ps1

下記の動作をしてくれます。

  1. outputに出力された請求書を標準プリンターに印刷
  2. 印刷後削除
print.ps1
# Get report list to print
$outputs=(Get-ChildItem output\*.fodg)

foreach($invoice in $outputs){

    # Print to Default Printer
    Start-Process $invoice -Verb Print | Stop-Process
    # After print and Delete
    Remove-Item $invoice

}

最後に

夢のDrawで帳票ができてしまいました。

  1. エンドユーザーが帳票を設計できる
  2. OSSで導入が低コスト

結構いけるんじゃないでしょうか?

メリー、クリスマス!