Edited at

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縦
      -invoice.png



  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で導入が低コスト

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

メリー、クリスマス!