仕事で帳票を出す作業があるんだけど、その帳票が古めかしい HTML で出力されてくる。
その帳票を IEから印刷するんだけど、HTML なのでテーブルの中間だろうと問答無用でページ分割してしまう。
「なんとか見やすくならないものかねぇ…」
と思って、IEをポチポチ弄ってると F12 で開発者用コンソールが出せるらしい。あぁ、これならなんとか改ページの挿入もできそう。
■やること
- テーブルを途中で改ページされないように印刷する
- ページ分割した際の垂直位置を top にする
- 文字の折り返しを禁止する
- 謎の
height="40"
を削除する
「1」は page-break-***
を入れればいいのだけど、IEはすでにページをまたがっている要素に対して page-break-before
を追加してもダメらしい。そのためダミー要素を追加してそちらで改ページを仕掛けるのだけど、テーブルとテーブルの間にテキストノードが入っていたりするので指定したテーブルの一つ前のテーブルに page-break-after
を設定することにした。
「2」はテーブルがいくつか入れ子になっているので一番親となるテーブルにだけ vertical-align: top
を設定する。
「3」はテーブルがウィンドウサイズに合わせて文字を折り返してしまうので white-space: pre
でそれを禁止する(nowrap
だとはみ出る可能性があるので使わない)。
「4」はなぜかよくわからんが1行だけ height="40"
がセットされているところがある…のでそこを削除する。(テンプレートの作成ミスではないだろうか)
各テーブルには id
属性がセットされているのでそれを利用する。ここでは T1
のような名前にする。
HTML の構造はこんな感じだったかなぁ(かなり適当)。
<tableid="T0"><tr><td>■帳票1 <tableid="T1"><tr><td></td></tr></table><br>■帳票2 <tableid="T2"><tr><td></td></tr></table><br>■帳票3 <tableid="T3"><tr><tdheight="40"></td></tr></table><br>■帳票4 <tableid="T4"><tr><td></td></tr></table></td></tr></table>
(function(){var RT, e, i, j; // 基幹テーブル RT = document.getElementById("T0"); // 指定のテーブルの1つ前のテーブル後に改ページ挿入 e = RT.getElementsByTagName("table"); for (i = 1; j = e[i]; i++) {switch (j.id) {case"T2": case"T3": case"T4": e[i - 1].style.pageBreakAfter = "always"; break; }}// テーブルセルスタイル指定 e = RT.getElementsByTagName("*"); for (i = 0; j = e[i]; i++) {switch (j.tagName.toLowerCase()) {case"table": // 将来使う予定?break; case"td": j.style.lineHeight = "1"; // 行間 j.style.textAlign = "left"; // 水平位置 j.style.verticalAlign = "middle"; // 垂直位置 j.style.whiteSpace = "pre"; // 折り返しif (j.hasAttribute("height")) j.removeAttribute("height"); // height 属性削除break; }}// 親テーブルセルスタイル指定 e = document.getElementById("T1").parentElement; e.removeAttribute("style"); // スタイル初期化 e.style.verticalAlign = "top"; // 垂直位置指定})();
改ページを入れる基準になるテーブルは配列に入れてたんだけど JavaScriptには in
みたいなメソッドがない…のだろうか(最近できるようになったみたい?)。
それほどテーブルの指定は多くないので switch
で対応することにした。
家に IE使える環境がないので開発者向けツールに貼り付けて動くかどうかはわからない。
追記
JavaScriptについてちょっと調べていたら、いろんな書き方が散在していていったいどの書き方が一般的(?)なのかわからなくなってきた。
自分はどちらかというと変数をあまり使いたがらないダメなタイプ(?)なので無名関数で組むのが好きかなぁ(length
で配列の長さを変数に入れるために変数を用意するとか嫌なんだよなぁ)。
(function(){// 基幹テーブルvar RT = document.getElementById("T0"); // td 要素一括指定スタイルvar td_style = { lineHeight : "1", // 行間 textAlign : "left", // 水平位置 verticalAlign: "middle", // 垂直位置 whiteSpace : "pre", // 折り返し}; // 指定のテーブルの1つ前のテーブル後に改ページ挿入 (function(){var e = RT.getElementsByTagName("table"); for (var i = 1; e[i] != null; i++) {switch (e[i].id) {case"T2": case"T3": case"T4": e[i - 1].style.pageBreakAfter = "always"; break; }}})(); // テーブルセルスタイル一括指定 (function(){var e = RT.getElementsByTagName("*"); for (var i = 0; e[i] != null; i++) {switch (e[i].tagName.toLowerCase()) {case"table": // 将来使う予定?break; case"td": for (var k in td_style) e[i].style[k] = td_style[k]; if (e[i].hasAttribute("height")) e[i].removeAttribute("height"); // height 属性削除break; }}})(); // 親テーブルセルスタイル指定 (function(){var e = document.getElementById("T1").parentElement; e.removeAttribute("style"); // スタイル初期化 e.style.verticalAlign = "top"; // 垂直位置指定})(); })();