見出し画像

kintoneの商品管理アプリからQRコードをラベル印刷する


はじめに

kintoneで商品管理アプリを作っているとき、「商品にQRコードを貼って読み込んだらその商品情報に飛べるようにしたいねー」ということになり、挑戦してみたので備忘録として記事を書きました。
全体的に意味を理解していないので、気になる方はご自身で調べてみてください。

作りたいもの

最終的に商品管理アプリのレコード詳細画面に印刷ボタンを設置して印刷できるようにしたい。あと、プレビューボタンも設置して右側にプリントのイメージを表示したい。

おおまかな流れ

  1. 各種インストール

  2. kintoneで商品管理アプリを作成する(省略)

  3. P-touch Editorでフォーマットを作成する

  4. bpac.jsをとってくる

  5. VSCodeでコーディング

  6. kintoneで検証

開発環境

足りないものがあれば準備する。

  • 商品管理アプリ
    kintoneで自作。今回使用するフィールドは後ほど説明します。

  • ブラウザ:今回はChrome

  • ラベルプリンター:Brother QL-800

  • ドライバー:P-touch Editor
    公式サイトから自分の環境に合わせてダウンロードしてください。

  • SDK:b-pac
    こちらも公式サイトからダウンロード。会員登録が必要でした。

  • Chrome拡張機能:Brother b-pac Extension
    InternetExpror以外のブラウザでは必要みたいです。

  • エディタ:Visual Studio Code
    bashシェルでコマンドを実行しました。Node.jsも使った。

  • 言語:JavaScript

kintoneで商品管理アプリを作成

今回使用したフィールドは以下のものです。
※業務フローとしては、営業員がお客様の自宅で商品を買い取り、中古品として販売することを想定しています。

用意するフィールド

  • 商品管理番号(文字列1行)
    →アプリ内で一意のものを設定

  • 営業員識別番号(文字列1行)
    →2ケタのアルファベット

  • 棚番号(文字列1行)
    →1ケタのアルファベット

  • 動作確認(ドロップダウン)
    →「○」「△」「×」「××」から選択

  • 商品レコードURL(リンク)
    →レコードを作成すると、このフィールドにレコードのURLが自動で入るようにしています。

  • printButton(スペース)
    →印刷ボタンとプレビューボタンを設置する場所

  • previewArea(スペース)
    →プレビューを表示する場所

P-touch Editorでフォーマットを作成する

P-touch Editorを開き、在庫管理アプリに合わせて.lbxファイルを作成します。大体の手順はこちらに書いてありました。
ひとつ注意しておかなければいけないことは、QRコードを表の中にいれないことです。QRコードを表に入れるとデータにURLをセットできなくなってしまいます。(←これで結構悩んだ)

オブジェクト名の設定

  • controlNumber
    →商品管理番号のテキストをセットします。

  • salesPerson
    →営業員識別番号のテキストをセットします。

  • shelfNumber
    →棚番号のテキストをセットします。

  • motionCheck
    →動作確認のテキストをセットします。

  • QRCode
    →商品レコードURLの値をセットします。データの欄を指定しなければいけないっぽいので、とりあえず[NULL]にしました。

このようになりました。
QRコードはデータに設定したURLの長さによって大きさが変わってしまうため、セルサイズ「中」で設定しています。

保存

ファイル名は「商品ラベル.lbx」で、「C:\商品ラベルプリント\」のフォルダに保存しました。
※パスをわかりやすくするため、あらかじめCドライブ直下に「商品ラベルプリント」というフォルダを作成しています。

bpac.jsをとってくる

b-pacをダウンロードすると、JavaScriptのサンプルフォルダにbpac.jsというものがあるので、これを後で使います。
あとでフォルダに格納するのでわかりやすいとこに置いておきます。

デフォルトだとココにあります。↓
C:\Program Files\Brother bPAC3 SDK\Samples\JavaScript

VSCodeでコーディング

説明が面倒なのでコマンド操作を書いておきます。
これ見ればできます!

  1. ディレクトリを作ってそのなかに入る
    $ mkdir webpack
    $ cd webpack

  2. プロジェクトを初期化する
    $ npm init

  3. 必要なツールをインストールする
    $ npm install -D webpack webpack-cli webpack-dev-server
    $ npm install -D babel-loader @babel/core @babel/preset-env core-js@3

  4. srcディレクトリを作成する
    $ mkdir src

  5. bpac.jsを配置する
    先ほどとってきたbpac.jsをこのsrcフォルダに入れてください

  6. labelPrint.jsを作成する(このファイルに詳細画面での処理を記述します。)
    $ touch src/labelPrint.js

  7. webpackフォルダ直下にwebpack.config.jsを作成する
    touch webpack.config.js

  8. 作成したファイル(labalPrint.jsとwebpack.config.js)の中身を記述する。(ソースコードと説明は後述)

  9. ビルドする
    $ npx webpack --mode development

labelPrint.js

import * as bpac from './bpac.js';
	
(function() {
	"use strict";
  //表示系イベント
    const indexShowE = 'app.record.index.show'; //一覧画面
    const indexEditShowE = 'app.record.index.edit.show'; //一覧画面の編集
    const createShowE = 'app.record.create.show'; //新規登録画面
    const editShowE = 'app.record.edit.show'; //編集画面
    const detailShowE = 'app.record.detail.show'; //レコード詳細画面
    //登録系イベント
    const indexEditSubmitE = 'app.record.index.edit.submit'; //一覧画面編集登録
    const createSubmitE = 'app.record.create.submit'; //新規登録
    const editSubmitE = 'app.record.edit.submit'; //編集登録
    //削除系イベント
    const indexDeleteE = 'app.record.index.delete.submit'; //一覧画面レコード削除
    const detailDeleteE = 'app.record.detail.delete.submit'; //詳細画面レコード削除
    //変更系イベント
    const createChangeE = (fieldCode) => { return 'app.record.create.change.'+ fieldCode }; //新規登録画面のフィールド値変更
    const editChangeE = (fieldCode) => { return 'app.record.edit.change.' + fieldCode }; //編集画面のフィールド値変更
    const indexEditChangeE = (fieldCode) => { return 'app.record.index.edit.change.' + fieldCode }; //一覧画面のフィールド値変更
    

    //showイベント
    kintone.events.on([detailShowE], (e) => {
		const record = e.record;
    	var printButtonArea = document.getElementById('user-js-printButton'); //printButtonのhtmlを取得
		
		//プリントボタン
		var printButton = document.createElement('input');
		printButton.value = 'QRコードを印刷';
		printButton.type = 'button';
		printButton.id = 'print-button';
		printButton.onclick = 'DoPrint';
		
		//プレビューボタン
		var previewButton = document.createElement('input');
		previewButton.value = '印刷プレビュー';
		previewButton.type = 'button';
		previewButton.id = 'preview-button';
		printButtonArea.appendChild(printButton);
		printButtonArea.appendChild(document.createElement('br'));
		printButtonArea.appendChild(previewButton);

		//プレビューエリア
		var previewArea = document.getElementById('user-js-previewArea'); //previewAreaのhtmlを取得

		const DATA_FOLDER = "C:\\商品ラベルプリント\\"; //バックスラッシュ2個!

		//値を取得する
		var controlNumberValue = record.商品管理番号.value;
		var salesPersonValue = record.営業員識別番号_結果.value;
		// var storeClerkValue = record.販売員識別番号_仕分.value;
		var motionCheckValue = record.動作確認.value;
		var shelfNumberValue = record.棚番号.value;
		var recordURLValue = record.商品レコードURL.value;
		
		//印刷ボタンイベント
		printButton.addEventListener('click', function() {
			DoPrint('');
		});

		//プレビューボタンイベント
		previewButton.addEventListener('click', function() {
			DoPrint('Preview.bmp');
		});

    	window.DoPrint = async function DoPrint(strExport)
        {
    		console.log('開始');
    		if(bpac.IsExtensionInstalled() == false)
    		{
    			const agent = window.navigator.userAgent.toLowerCase();
                const isedge = agent.indexOf('edg') !== -1;
                if (isedge)
                    window.open('https://microsoftedge.microsoft.com/addons/detail/brother-bpac-extension/kmopihekhjobijiipnloimfdgjddbnhg', '_blank');
                const ischrome = (agent.indexOf('chrome') !== -1) && (agent.indexOf('opr') === -1);
                if (ischrome)
                    window.open('https://chrome.google.com/webstore/detail/ilpghlfadkjifilabejhhijpfphfcfhb', '_blank');
                return;
    		}
    
            printButton.disabled = true; //印刷ボタンを活性化する
    		try{
    			const nItem = "商品ラベル.lbx";
    			// const strPath = DATA_FOLDER + theForm.cmbTemplate.options[nItem].value;
    			const strPath = DATA_FOLDER + nItem; //テンプレートのパスを宣言
    			const objDoc = bpac.IDocument; //IDocumentを初期化
                const ret = await objDoc.Open(strPath);
    			// console.log(strPath);
    			if(ret == true)
    			{
    				const controlNumber = await objDoc.GetObject("controlNumber");
    				controlNumber.Text = controlNumberValue; //商品管理番号
    				const salesPerson = await objDoc.GetObject("salesPerson");
    				salesPerson.Text = salesPersonValue; //営業員
    				const shelfNumber = await objDoc.GetObject("shelfNumber");
    				shelfNumber.Text = shelfNumberValue; //棚番号
    				const motionCheck = await objDoc.GetObject("motionCheck");
    				motionCheck.Text = motionCheckValue; //動作確認
					// const QRCode = await objDoc.GetObject("QRCode");
					const setBarcodeResult= await objDoc.SetBarcodeData(0, recordURLValue); //QRコードにURLをセットする
					console.log(setBarcodeResult);
    				if(strExport == "")
    				{
    					objDoc.StartPrint("", 0);
    					objDoc.PrintOut(1, 0);
    					objDoc.EndPrint();
    				}
    				else
    				{
						if(document.getElementById("preview-img") != null) {
							document.getElementById('preview-img').remove();
						}
    					const image = await objDoc.GetImageData(4, 0, 100);
    					const img = document.createElement('img');
						img.id = 'preview-img';
    					img.src = image;
						previewArea.appendChild(img);
    				}
    
    				await objDoc.Close();
    			}
    		}
    		catch(e){
                // console.log(e);
            }
            printButton.disabled = false;
    		console.log('終了');
    	}
		return e;
	});

webpack.config.js

const path = require('path');

module.exports = {
  entry: {
    'labelPrint': './src/labelPrint.js', //'ビルドした後のファイル名': 'ファイルのパス'
    'bpack': './src/bpac.js' //bpacも指定
  },
  // webpack 5 を利用していて、IE 対応する場合は以下のコメントを外す
  // target: ['web', 'es5'],
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  useBuiltIns: 'usage',
                  corejs: 3
                }
              ]
            ]
          }
        }
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  externals: {
    jquery: 'jQuery'
  }
};

ビルドまで完了するとdistディレクトリの中に自動でファイルが作成されます。(labelPrint.jsとbpac.js)

最終的なフォルダ

最終的なフォルダの中身はこんな感じです。

kintoneで検証

まずdistディレクトリ内に作成された2つのファイルを商品管理アプリで読み込みます。↓

保存して、適当に作成したレコードを開くとボタンが表示されました!
プレビューボタンも機能しています↓

「商品ラベル.lbx」をあらかじめ開いて、印刷ボタンを押すとラベルが出てきました!

さいごに

b-pacの情報が少なくてかなり苦戦しました。
同じことをする人は少ないと思いますが、流れだけでも参考になったら幸いです。

この記事が気に入ったらサポートをしてみませんか?