備忘ですが、

誰かの役に立てばいい

【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で印刷ボタンをクリック後。
最低限の設定だとこんな感じになります。※データは架空のダミーデータです。
f:id:bibouroq:20181227002636p:plain

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  
});

出来上がり

スタイル変更後。
f:id:bibouroq:20181227003132p:plain

難点も

ブラウザの仕様かと思いますが、

  • レコードが数百件になると印刷プレビューの表示が遅くなる
  • IEでは印刷プレビューが表示されない
  • 折り返しなしの表示が難しい

→printJSの設定に

gridStyle: 'border: 1px solid lightgray; margin-bottom: -1px; white-space: nowrap;',

white-space: nowrap;を入れると文字列を折り返しなしにできますが、横幅が大きすぎると印刷時にうまく用紙内に収まらなくなります。
IE、Edge、Chromeで確認。Chromeが一番良い感じに収まりやすい)
収まりきらずはみでた場合、ブラウザの印刷設定で余白を狭くする、倍率を下げる、用紙を大きくする、などが必要になります。

自分で別ウィンドウにテーブル作ってCSS書いてwindow.print()させて・・・と同じような動作をしてる感じです。