HTML文書PDF印刷の改良

以前、HTML文書を作成しPDF変換する スクリプトを作成しましたが、これを改良してみました。

 

(1)枠幅を固定したい。

各セル内の文字数が十分に多ければ気にならないのですが、少ない場合、表ごとに列の大きさがバラバラになっていました。右余白が大きくなってしまう事も有り、やや見苦しい印象がありました。

 <table border="1" width="100%">
<caption><span style="font-size: 150%;">${key}</span></caption>
<meta http-equiv="content-type" charset="utf-8">
 <tr>
<th width="6%">第1列</th>
<th width="32%">第2列</th>
<th width="30%">第3列</th>
<th width="32%">第4列</th>
</tr>

と見出し行で幅指定をしてやることで、枠幅を固定することができました。 width は %表示だけでなくピクセル数でも指定できます。

 

(2)ヘッダーを付けたい

wkhtmltopdf では、「 --header-right 文字列 」オプションでヘッダーを指定できるはずなのですが、上手くゆきません。色々調べるとwkhtmltopdf にはQTパッチ版と、そうでないものがあることが分かりました。そこで、QTパッチ版を再インストールするとオプションが作用するようになりました。 

 wkhtmltopdf -q -T ${top_margin} -B ${bottom_margin} \
    -L ${left_margin} -R ${right_margin} \
    --print-media-type \
    --header-right "${key[$i]}" --header-spacing 5 \
    ${temp_html} ${temp_pdf} \
    >/dev/null 2>&1    

 (3)セルの途中で改ページさせない

ところが逆にQTパッチ版の wkhtmlpdf では用紙の大きさに合わせて、平気でセルの途中で改ページをするようになってしまいました。

f:id:S_E_Hyphen:20201010122215p:plain

これは少し都合が悪いので、HTML文書内にスタイルシートを埋め込むように改良しました。

<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
table { page-break-inside:auto }
tr { page-break-inside:avoid; page-break-after:auto }
</style>
</head>
<body>
<table border="1" width="100%">
<caption><span style="font-size: 150%;">2020年10月01号复习</span></caption>

 

以上の変更を加えた make_pdf と make_html のリストです。

#!/bin/bash
host=xxx.xxx.xxx.xxx
database=dddddd declare -a key=( \ `mysql -N -h ${host} ${database} << _SQL_ select word from keyword where word like "%复习" group by word order by word; _SQL_ `) left_margin=25 # 左余白の設定 right_margin=15 # 右余白の設定 top_margin=20 # 上余白の設定 bottom_margin=18 # 下余白の設定 # 一時ファイルの作成 temp_html=`mktemp ./XXXX.html` temp_pdf=`mktemp ./XXXX.pdf` output_pdf="review_note.pdf" for (( i=0; i<${#key[*]}; i++ )) do echo ${key[$i]} # データベースよりKEYオプションに応じて検索を実施し、 # HTML文書を作成する自作コマンド ./make_html key=${key[$i]} > ${temp_html} # wkhtmltopdf にて PDF文書に変換 # ( 余白の設定については https://stackoverrun.com/ja/q/10907299 を参考) wkhtmltopdf -q -T ${top_margin} -B ${bottom_margin} \ -L ${left_margin} -R ${right_margin} \ --print-media-type \ --header-right "${key[$i]}" --header-spacing 5 \ ${temp_html} ${temp_pdf} \ >/dev/null 2>&1 # loop 1回目は${temp_pdf}を${output_pdf}に変名しループを離脱 if [ $i -eq 0 ] then mv ${temp_pdf} ${output_pdf} else # pdftk で結合の実施 # 一時ファイル ${united_pdf} に出力し、 # ${output_pdf} にファイル名変更することで # 再帰的な結合を繰り返す united_pdf=`mktemp ./XXX.pdf` pdftk ${output_pdf} ${temp_pdf} cat output ${united_pdf} mv ${united_pdf} ${output_pdf} fi done rm ${temp_html} ${temp_pdf} 

 

#!/bin/bash
key=`getparstr $# "$*" "key"`

#################################################
host=xxx.xxx.xxx.xxx
database=dddddd
temp=`mktemp ./XXXX` if [ ! -z "${key}" ] then mysql -h ${host} -N ${database} << _SQL_ > $temp select v.id,ch,py,ja from vocabulary v right join keyword k on k.id=v.id where k.word like "%${key}%" order by k.sub_id,v.id; _SQL_ else rm $temp; exit fi cat << _HEADER_ > /dev/stdout <html> <head> <meta charset="UTF-8"> <style type="text/css"> table { page-break-inside:auto } tr { page-break-inside:avoid; page-break-after:auto } </style> </head> <body> <table border="1" width="100%"> <caption><span style="font-size: 150%;">${key}</span></caption> <meta http-equiv="content-type" charset="utf-8"> <tr> <th width="6%">番号</th> <th width="32%">中国語</th> <th width="30%"> 拼音</th> <th width="32%">日本語</th> </tr> _HEADER_ cat $temp |\ awk -F"\t" --assign line="$line" \ '{printf " <tr valign=\"top\">\n"} \ {printf " <td align=\"right\">%d</td>\n",$1} \ {printf " <td>%s</td>\n",$2} \ {printf " <td style=\"font-size:85%;\">%s</td>\n",$3} \ {printf " <td style=\"font-size:80%;\">%s</td>\n",$4} \ {printf " </tr>\n"}' >> /dev/stdout cat << _FOOTER_ >> /dev/stdout </table></body></html> _FOOTER_ rm $temp; exit