kintone のレコードを紙で出したい、という要望はよくあります。ブラウザーの印刷をそのまま使うと、メニューやサイドバーまで印刷され、1件が何枚にも分かれます。
この記事では、作業日報や KY 活動記録を A4 縦の帳票にして印刷するプラグインのコードで、次の4つを見ます。PDF のライブラリーは使わず、HTML と CSS とブラウザーの印刷だけで作っています。
- 帳票を画面の上に重ね、印刷では帳票だけを出す CSS
- フィールドの値を、帳票に載せる文字に整える
- リッチエディターの HTML から文字だけを取り出す
- A4 の1枚に収まらない帳票を、印刷の前に知らせる
コードは2026年11月8日に kintone の開発環境で動かして確かめています。画面の写真は、その環境の架空のデータです。

印刷(PDF)の1ページ目の上の部分。開始は UTC の値を日本時間に直し、金額は桁区切りと単位つき、備考はリッチエディターから文字だけを取り出している
1. 帳票だけを印刷する CSS
ボタンを押すと、body の直下に #gbd-report を足し、body に gbd-printing のクラスを付けます。画面では、帳票を全面に重ねて表示します(kintone/daily-report/src/css/desktop.css)。
#gbd-report{position:fixed;inset:0;z-index:100000;overflow:auto;background:#d8d8d8;color:#111;font-family:sans-serif;-webkit-print-color-adjust:exact;print-color-adjust:exact}
.gbd-sheet{box-sizing:border-box;width:210mm;min-height:297mm;margin:12px auto;padding:10mm;background:#fff}
1枚の帳票(.gbd-sheet)は幅 210mm、高さ 297mm。CSS の mm で書くと、画面でも紙と同じ比率で見えます。print-color-adjust:exact は、見出しの灰色の背景を印刷でも消さないための指定です。
印刷のときの指定はこうです。
@media print{
@page{size:A4 portrait;margin:10mm}
body.gbd-printing{height:auto!important;overflow:visible!important;background:#fff!important}
body.gbd-printing>*:not(#gbd-report){display:none!important}
/* 写真台帳プラグインと同じアプリに入れても、帳票が隠れないようにする */
html body.gbd-printing>div#gbd-report{display:block!important;position:static;overflow:visible;background:#fff}
.gbd-bar{display:none!important}
.gbd-sheet{width:auto;min-height:0;margin:0;padding:0;outline:0!important;break-after:page}
.gbd-sheet:last-child{break-after:auto}
}
-
body.gbd-printing>*:not(#gbd-report)で、kintone の画面(帳票以外のbodyの子)をすべて隠します。 - 画面では
position:fixedだった帳票を、印刷ではposition:staticに戻します。固定のままだと、画面からはみ出した2ページ目以降がうまく印刷されないことがあるためです。 -
@pageの余白を 10mm にしたので、印刷では.gbd-sheetの余白(padding)を0にします。画面のpadding:10mmと同じ見た目になります。 -
break-after:pageで、1件ごとに改ページします。最後の1枚だけは外して、白紙が1枚増えないようにします。 - 表の行と署名欄には
break-inside:avoidを付け、行の途中でページが切れないようにしています。
開発環境で100件の帳票を PDF にすると、すべて A4 縦(210×297mm)で、白紙のページはありませんでした(1枚に収まらない1件が3ページになり、合わせて102ページ)。
コメントにあるとおり、同じアプリに入れる別のプラグイン(写真台帳)も、印刷では body>*:not(#gbk-ledger){display:none!important} で「自分以外」を隠します。そのままでは日報の帳票まで消えるので、html body.gbd-printing>div#gbd-report のように詳しさ(詳細度)を上げた !important で、自分の帳票を出し直しています。
2. フィールドの値を帳票の文字に整える
REST API やイベントで届く値は、画面の表示とは違う形です。そのまま印刷すると読みにくいので、型ごとに整えます(kintone/daily-report/src/js/desktop.js)。
function display(field, property) {
if (!field || field.value === null || field.value === undefined || field.value === '') return '';
var value = field.value;
var prop = property || {};
switch (field.type) {
case 'DATETIME':
case 'CREATED_TIME':
case 'UPDATED_TIME':
return localTime(value);
case 'RICH_TEXT':
return richText(value);
case 'NUMBER':
case 'CALC':
if (field.type === 'CALC' && prop.format && prop.format !== 'NUMBER' && prop.format !== 'NUMBER_DIGIT') return String(value);
var number = (prop.digit === true || prop.digit === 'true' || prop.format === 'NUMBER_DIGIT') ? withDigits(value) : String(value);
if (!prop.unit) return number;
return prop.unitPosition === 'BEFORE' ? prop.unit + number : number + prop.unit;
default:
break;
}
if (Array.isArray(value)) return value.map(function(v) { return (v && typeof v === 'object') ? (v.name || v.code || '') : String(v); }).join('、');
if (typeof value === 'object') return value.name || value.code || '';
return String(value);
}
property は、/k/v1/app/form/fields.json で取ったフィールドの設定です。値だけでは分からない「桁区切りを出すか」「単位は何か、前か後ろか」をここから読みます。
-
日時:値は UTC の
2026-11-02T23:30:00Zの形で届きます。日本時間では翌日の 08:30 なので、端末の時刻に直します。
// 日時はUTCで届くので、端末の時刻に直して「2026-11-02 08:30」にする
function localTime(value) {
var date = new Date(value);
if (isNaN(date.getTime())) return value;
return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate()) + ' ' + pad(date.getHours()) + ':' + pad(date.getMinutes());
}
-
数値・計算:桁区切りは、整数の部分にだけ付けます。小数の部分に付けないよう、
.で分けてから正規表現をかけます。
function withDigits(value) {
var parts = String(value).split('.');
if (!/^-?\d+$/.test(parts[0])) return String(value);
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return parts.join('.');
}
- 計算フィールドで表示形式が日付や時間のものは、数として扱わず、そのまま出します。
-
ユーザー選択・チェックボックスなど:値が配列なので、
name(ユーザーなど)か文字列を「、」でつなぎます。
3. リッチエディターから文字だけを取り出す
リッチエディターの値は HTML です。innerHTML で帳票に入れると、書式が崩れるだけでなく、スクリプトが動くおそれもあります。そこで、描画しない文書として読み、文字と改行だけを取り出します。
var BLOCKS = {P: 1, DIV: 1, LI: 1, TR: 1, H1: 1, H2: 1, H3: 1, H4: 1, H5: 1, H6: 1, BLOCKQUOTE: 1, PRE: 1};
// (中略)
// リッチエディターのHTMLは、描画しない文書で読んで文字だけ取り出す
function richText(html) {
var doc = new DOMParser().parseFromString(String(html), 'text/html');
var out = '';
(function walk(node) {
for (var child = node.firstChild; child; child = child.nextSibling) {
if (child.nodeType === 3) {
out += child.nodeValue;
} else if (child.nodeType === 1) {
if (child.nodeName === 'BR') {
out += '\n';
} else if (child.nodeName !== 'SCRIPT' && child.nodeName !== 'STYLE') {
walk(child);
if (BLOCKS[child.nodeName] && out.slice(-1) !== '\n') out += '\n';
}
}
}
})(doc.body);
return out.replace(/\n+$/, '');
}
-
DOMParserで作った文書は画面に出ないので、中の<img onerror=...>なども動きません。開発環境で<img src="x" onerror=...>と<script>を入れた値を帳票にしても、どちらも動かず、段落と<br>と箇条書きの区切りが改行になりました。 -
<br>と、段落などのブロックの終わりを改行にします。textContentだけだと段落の区切りが消えて1行につながるので、木をたどって改行を足しています。 - 帳票のセルには
textContentで入れ、CSS のwhite-space:pre-wrapで改行を見せます。
帳票の部品はすべて document.createElement と textContent で作っていて、HTML の文字列を組み立てていません。レコードの値に < が入っていても、そのまま文字として出ます。
4. 1枚に収まらない帳票を知らせる
本文が長いと、1件が2枚にまたがります。印刷してから気づくと紙がむだになるので、画面に出した時点で数えます。
// A4の印刷範囲(余白10mmを除いた高さ277mm)を超えた帳票を数える
var probe = element('div', 'gbd-probe');
root.appendChild(probe);
var limit = probe.getBoundingClientRect().height;
root.removeChild(probe);
var over = 0;
Array.prototype.forEach.call(root.querySelectorAll('.gbd-inner'), function(inner) {
if (limit && inner.getBoundingClientRect().height > limit + 1) {
inner.parentNode.classList.add('gbd-over');
over++;
}
});
.gbd-probe{height:277mm;width:1px;position:absolute;visibility:hidden}
.gbd-sheet.gbd-over{outline:3px solid #c62828}
297mm から上下の余白 10mm ずつを引いた 277mm の見えない箱を置き、その高さをピクセルで測ります。mm とピクセルの換算を自分で書かずに、ブラウザーに測らせるのがこつです。中身(.gbd-inner)がそれより高い帳票に赤い枠を付け、上のバーに「1枚に収まらない帳票 ○件(赤枠。印刷すると2枚以上になります)」と出します。赤枠は @media print で消すので、紙には出ません。
5. 押した時点の内容で作る
詳細画面のボタンは、画面を開いたときの event.record ではなく、押した時点の内容を使います。
// 押した時点の内容を使う。取れなければ画面を開いたときの内容
var current = kintone.app.record.get();
var record = (current && current.record) || event.record;
まとめ
- 帳票は
bodyの直下に重ね、印刷では:not()で帳票以外を隠す。@pageで A4 と余白を決める。 - 値はフィールドの設定(桁区切り・単位)と型を見て整える。日時は UTC から端末の時刻へ。
- リッチエディターは
DOMParserで読み、文字と改行だけを取る。 - 1枚に収まるかは、277mm の箱をブラウザーに測らせて比べる。
ソースと配布先
この記事のコードは kintone プラグイン「作業日報・KY記録プリント」(MIT License)の一部です。入れ方と設定:https://genbakoe.com/kintone/daily-report/?utm_source=qiita&utm_medium=referral&utm_campaign=kintone-plugin-a4-print / ソース:https://github.com/Genbacoe/kintone-plugins/tree/main/daily-report/src
※ kintone はサイボウズ株式会社の登録商標です。このプラグインと記事は、サイボウズ株式会社の公式のものではありません。
