【kintone】で宛名ラベルを作ってみる
やりたいこと→kintoneに作った住所録を使って、ワンクリックで宛名ラベル印刷画面を生成する。
世の中にはプリントクリエイターってプラグインがあるじゃろがいって言われそう。
(2018/12/24 一覧表示の方法をVueからHandsontableへ変更)
参考サイト
Handsontableを使ってkintoneをExcelライクに入力しよう その1 – cybozu developer network
Handsontable 使い方メモ1(基本) - Qiita
paper.cssを使ってブラウザだけでExcelのデータを差し込み印刷する - Qiita
paper.cssを使ってブラウザだけで名刺を印刷する - Qiita
ライブラリとか
- handsontable.full.min.js、handsontable.full.min.css (ver 6.2.0)
- underscore-min.js
(CybozuCDNより)
- カスタマイズビューを使用(ページネーションを表示するはオフ)
HTML
<div id="my-customized-view" ></div> <!-- 子ウィンドウHTML --> <textarea id="TB" style="display: none;"> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>印刷画面</title> <style type="text/css"> @page { margin: 0 } body { margin: 0 } .sheet { margin: 0; overflow: hidden; position: relative; box-sizing: border-box; page-break-after: always; } /** Paper sizes **/ body.A4 .sheet { width: 210mm; height: 296mm } /** Padding area **/ .sheet.padding-10mm { padding: 10mm } .sheet.padding-15mm { padding: 15mm } .sheet.padding-20mm { padding: 20mm } .sheet.padding-25mm { padding: 25mm } /** For screen preview **/ @media screen { body { background: #e0e0e0 } .sheet { background: white; box-shadow: 0 .5mm 2mm rgba(0,0,0,.3); margin: 5mm; } } /** Fix for Chrome issue #273306 **/ @media print { body.A4 { width: 210mm } } /** 印刷画面 **/ table.print { position: absolute; top: 50%; left: 50%; width: 172.8mm; height: 254.6mm; margin: -127.3mm 0 0 -86.4mm; border-collapse: collapse; font-family: "MS 明朝"; } table.print td { border: 1px solid; /** 使用時は消す **/ border-color: black; /** 使用時は消す **/ border-collapse: collapse; position: relative; width: 86.4mm; height: 42.3mm; } table.print p{ position: relative; width: 75.0mm; margin: 0; left: 5mm; } table.print p.zipcode { font-size: 11pt; } table.print p.address1 { font-size: 11pt; } table.print p.address2 { font-size: 11pt; } table.print p.client { font-size: 11pt; } table.print p.namae { font-size: 13pt; } table.print br { line-height: 6pt; } </style> </head> <body class="A4"> <section class="sheet" id="originSheet"> <table class="print"> <tbody> <tr> <td> <div class="data"> <!-- 開発時確認用 --> <p class="zipcode">123-4567</p> <p class="address1">○○県○○○市○○○1-1-1</p> <p class="address2">△△△△△△ビル</p> <br> <p class="client">株式会社サンプルホールディングス</p> <p class="namae">代表取締役 サンプル 太郎 様</p> </div> </td> <td></td> </tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr> <tr><td></td><td></td></tr> </tbody> </table> </section> </body> </html> </textarea>
JavaScript
(function() { "use strict"; kintone.events.on("app.record.index.show", function(event) { if (event.viewId !== 一覧IDを入れる) return event; const fields = ['役職','氏名','会社名','郵便番号','住所1','住所2']; function fetch(opt_offset, opt_records) { var offset = opt_offset || 0; var records = opt_records || []; var appId = kintone.app.getId(); var query = kintone.app.getQueryCondition(); var query2 = kintone.app.getQuery(); var sort = query2.split(/by|limit/); var params = { app: appId, query: query + ' order by' + sort[1] + ' limit 500 offset ' + offset }; 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; }); } var TB = document.getElementById("TB").value; function show(datalist){ var obj = window.open(); obj.document.open(); obj.document.write(TB); obj.document.close(); // 12枚を超える場合はページを増やす var sheets = Math.ceil(datalist.length / 12); _.times(sheets - 1, function () { var clone = obj.document.getElementById('originSheet').cloneNode(true); obj.document.body.appendChild(clone); }); // underscore.js のテンプレート機能でテーブルのセルにデータを流し込む var compiled = _.template( '<div class="data"><p class="zipcode"><%= data.zipcode %></p>' + '<p class="address1"><%= data.address1 %></p>' + '<p class="address2"><%= data.address2 %></p>' + '<br>' + '<p class="client"><%= data.client %></p>' + '<p class="namae"><%= data.namae %> 様</p></div>'); var cells = obj.document.getElementsByTagName('td'); _.each(datalist, function (value, key) { cells[key].innerHTML = compiled({"data": value}); }); obj; } fetch().then(function(myrecords) { var records = myrecords; function allprint(records) { var datalist = []; for (let i = 0; i < records.length; i++) { let listrow = { "namae": records[i][fields[0]].value +' '+ records[i][fields[1]].value, "client": records[i][fields[2]].value, "zipcode": records[i][fields[3]].value, "address1": records[i][fields[4]].value, "address2": records[i][fields[5]].value }; datalist.push(listrow); } show(datalist); } var button = document.createElement("button"); button.id = 'my_index_button'; button.textContent = "表示レコードを1ラベルずつ作成"; button.addEventListener("click", function() { allprint(records); }); var label = document.createElement('label'); label.appendChild(button); label.appendChild(document.createTextNode(" 表示件数:"+ records.length + " 件")); if (document.getElementById('my_index_button') !== null) { kintone.app.getHeaderMenuSpaceElement().textContent = null; } kintone.app.getHeaderMenuSpaceElement().appendChild(label); //Handsontableで表と行ボタン作成 var container = document.getElementById('my-customized-view'); var columns = []; for(let i = 0;i < fields.length; i++){ columns[i] = {data: fields[i] + '.value', title: fields[i], editor: false}; } for(let i =0; i<records.length; i++) { let record = records[i]; record["リンク用HTML"] = '<a href="/k/' + kintone.app.getId() + '/show#record=' + record.$id.value + '">' + record.$id.value +'</a>'; } columns.unshift({data: "リンク用HTML", renderer: 'html', title:'レコード番号', editor: false}); function showbutton(instance, td , row, col, prop, value, cellProp){ let button = document.createElement("button"); button.textContent = "作成"; button.addEventListener("click", function() { var datalist = []; var record = cellProp.instance.getSourceDataAtRow(row); for(let i =0;i < 12; i++){ let listrow = { "namae": record[fields[0]].value +' '+ record[fields[1]].value, "client": record[fields[2]].value, "zipcode": record[fields[3]].value, "address1": record[fields[4]].value, "address2": record[fields[5]].value }; datalist.push(listrow); } show(datalist); }); td.innerHTML = ''; td.appendChild(button); } columns.unshift({data: "ボタン", renderer: showbutton, title: 'ラベル', editor: false}); var hot = new Handsontable(container, { data: records, minSpareRows: 0, contextMenu: false, fillHandle: false, columns: columns }); }); }); })();
出来上がり
個人情報は架空のダミーデータ。
絞り込みレコードを全てラベル化
1レコードのみラベル化