【kintone】一覧を印刷するカスタマイズ:Print.js
やりたいこと→一覧表示をkintoneからワンクリックで印刷する
標準でそういう機能がなく、一手間二手間必要になります。
よくあるご質問 | 「一覧」を印刷することはできますか?
需要がないのか、ペーパーレス推進の信念があるんでしょうか・・・。
Print.js
Print.js - Javascript library for HTML elements, PDF and image files printing.
リンク先のCDNを利用するか、jsファイルをダウンロードしてkintoneにアップロードします。
JSON形式のデータを表にして印刷してくれる機能があるのでそれを使用します。
JavaScript
※フィールドコードが印刷時の表の列名になります。
※kintoneで必ず作成される「(すべて)」という一覧とカスタマイズビューは印刷できません。
(function() { "use strict"; kintone.events.on("app.record.index.show", function(e) { if(e.viewType === 'custom') return; var appId = kintone.app.getId(); var viewName = e.viewName; var query = kintone.app.getQueryCondition(); var query2 = kintone.app.getQuery(); var sort = query2.split(/by|limit/); //列名取得 kintone.api(kintone.api.url('/k/v1/app/views', true), 'GET', {app: appId}, function(resp) { var fields = resp.views[viewName].fields; // 全件取得関数 function fetch(opt_offset, opt_records) { var offset = opt_offset || 0; var records = opt_records || []; var params = { app: appId, query: query + ' order by' + sort[1] + ' limit 500 offset ' + offset, fields: fields }; return kintone.api('/k/v1/records', 'GET', params).then(function(resp) { records = records.concat(resp.records); if (resp.records.length === 500) { return fetch(offset + 500, records); } return records; }); } //関数実行、{列名:値}になるよう組み替える fetch().then(function(resp){ var records = resp; var data = []; for(var i = 0; i < records.length; i++){ var record = {}; for(var key in records[i]){ if(records[i][key].value === null){ records[i][key].value = ''; //nullを文字として表示しないようにする } record[key] = records[i][key].value; } data.push(record); } var print_button = document.createElement('button'); print_button.id = 'pb'; print_button.innerHTML = '印刷'; print_button.onclick = function(){ printJS({ printable: data, properties: fields, type: 'json', }); }; if (document.getElementById('pb') !== null) { var element = document.getElementById("pb"); element.parentNode.removeChild(element); } kintone.app.getHeaderMenuSpaceElement().appendChild(print_button); return; }); }); }); })();
Chromeで印刷ボタンをクリック後。
最低限の設定だとこんな感じになります。※データは架空のダミーデータです。
Print.jsのスタイル変更
printJS({ printable: data, properties: fields, type: 'json', //見出し。htmlタグが使える header: '住所録', //見出しのスタイルを変更したい時 headerStyle: 'font-weight: 100; color: #3498db;', //列名のスタイルを変更したい時 gridHeaderStyle: 'font-size: 11px; color: #fff; background-color: #3498db; border: 1px solid #3498db;', //グリッドのデータ部分のスタイルを変更したい時 gridStyle: 'font-size: 11px; border: 1px solid #3498db; margin-bottom: -1px; white-space: nowrap;', //ページ毎に列名を表示するかどうか。デフォルトはtrue repeatTableHeader: false });
出来上がり
スタイル変更後。
難点も
ブラウザの仕様かと思いますが、
- レコードが数百件になると印刷プレビューの表示が遅くなる
- IEでは印刷プレビューが表示されない
- 折り返しなしの表示が難しい
→printJSの設定に
gridStyle: 'border: 1px solid lightgray; margin-bottom: -1px; white-space: nowrap;',
white-space: nowrap;を入れると文字列を折り返しなしにできますが、横幅が大きすぎると印刷時にうまく用紙内に収まらなくなります。
(IE、Edge、Chromeで確認。Chromeが一番良い感じに収まりやすい)
収まりきらずはみでた場合、ブラウザの印刷設定で余白を狭くする、倍率を下げる、用紙を大きくする、などが必要になります。
自分で別ウィンドウにテーブル作ってCSS書いてwindow.print()させて・・・と同じような動作をしてる感じです。