この前の案件でTCPDFでCODE39のバーコードを表示することがあり、
バーコード小さくしてを印刷すると黒い線が太くて白い部分がつぶれるので
TCPDF自体を修正し、黒線を細くすることで読取精度を上げてみました。
以下修正個所です。
WEBシステム開発等で気付いたことなどをまとめていきます。
この前の案件でTCPDFでCODE39のバーコードを表示することがあり、
バーコード小さくしてを印刷すると黒い線が太くて白い部分がつぶれるので
TCPDF自体を修正し、黒線を細くすることで読取精度を上げてみました。
以下修正個所です。
foreach ($arrcode['bcode'] as $k => $v) { // modified $v['w'] にバーコード1線分の太さ1か3で入っているので細さを調整したい数値(0.1)をセット $bw= ($v['w'] > 1) ? $v['w'] * $xres - 0.1 : $v['w'] * $xres + 0.1; if ($v['t']) { // draw a vertical bar $ypos = $y + $vpadding + ($v['p'] * $barh / $arrcode['maxh']); $this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh / $arrcode['maxh']), 'F', array(), $style['fgcolor']); } $xpos += $bw }
これで認識率上がりました。0.1の数値を調整することでもうちょっと認識率上げれそうでした。
cakephp入力フォームで、前回と変更になった入力値は入力文字を変更(赤く)して表示したい場合のサンプルです。
前提条件
前回入力した値と今回入力する値は別で情報を管理します。
その上で、前回と今回の差がわかる状態で判断します。
モデルはSampleを使用します。
いつもお世話になってるTCPDFですが
VER 5.2.000よりフォント・サブセットを使用できるのは知っていたのですが
日本語で使用するとCPUとメモリを使いすぎて使い物になりませんでした・・・
今までどおりフォントの全て埋め込みで対応していたのですがやはり3MBオーバーは重いなーと思っていました。(バックアップ用に生成したPDFとか置くのはとても無理でした)
以前案件で軽いPDFを出す必要がありだめもとで新しいTCPDF(6系)を使ってみたところ・・・
使えるようになってました!!(数100kbとかで出力できたりします。)
これでお客さんに重いって言われなくなります!
以下サンプルと注意事項です。
データベースのテーブルに対して、
・指定したキーのデータが存在していないなら追加したいが、あるのなら内容を更新したい
ということがあると思います。
そういう時、普通にプログラムで処理すると
1.SELECT文でデータの存在確認
2.データが存在しないならINSERT文で新規追加
3.データが存在するならUPDATE文で上書き
となると思います。
これでももちろん問題はないのですが、MySQL上で1.2.3.を一文で行うSQLも存在します。
PHPExcelである場所からある場所までのセルに対して操作をしたい時は、getStyle( “A4:G37” )のように指定したら良いのですが、プログラムで動的にする場合、Y座標は数字なので問題無く指定できるのですが、X座標はアルファベットなので動的に指定する事が出来ません。
そこで便利なのがPHPExcel_Cell::stringFromColumnIndex()です。
これは列の数字からアルファベットを返してくれる関数で、PHPExcel_Cell::stringFromColumnIndex(10)と渡すとKと返してきてくれます。
ですので、下記のように指定してあげるとgetStyle( “A4:G37” )のように指定することが可能になります。
$col = PHPExcel_Cell::stringFromColumnIndex(6); // 列の数字からアルファベットに変換 $sheet->getStyle( "A4:{$col}37" )->getFont()->setSize(10);// フォントサイズの指定
javascriptの拡張ライブラリ、jQueryの便利さはWebアプリケーション開発に携わっている皆さんにとっては自明のことだと思います。
そしてそのjQueryをベースにしてインタラクティブなUIをブラウザ上で実現してしまうのがjQueryUIライブラリです。
コレもご存知のことと思いますが……(^^;
このjQueryUIではUI操作の基本となるDraggable(ドラッグ),Droppable(ドラッグしたものを落とす),Resizable(大きさを変える),Selectable(選択する),Sortable(順番を並び替える)というインタラクティブ動作を支えるライブラリがあるのですが、一番UI的に受けがいいのはSortableではないかと思います。
たとえばこんなのです↓
あるPHPプログラムから他のプログラムを呼び出す、ということが時々あります。
API的に独立したプログラムに引数を渡して、結果を戻り値で得る、というような場合ですね。
そんな時、使うのがfile系の関数。
file_(f)ではじまるファイルを操作する関数は、同時にURLに対しても同じように動作する、という仕様に驚きを隠せないのは僕だけでしょうか。
URLが指し示すプログラムに対してfopenで開いてから引数を渡して戻り地を得る、という流れでももちろんできるようなのですが、今日のタイトルのように引数を渡して戻り値を得るだけであれば、
bootstrapのpopoverでdatepickerを使う際の手続きとpopoverしてから、popover以外をクリックするとpopoverが消える。ただし、datepicker表示中には消えないようにする方法をサンプルとしてまとめました。
以前下記の記事を書かせていただいたのですが、保存の所で想定の動きをしてくれない場合があるので注意が必要です。
————————————————————–
↓↓↓↓↓↓↓↓↓ここから前回の記事↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
————————————————————–
多対多のデータを扱うのにHasAndBelongsToManyをモデルで指定してあげると
簡単にデータの取り出しや保存が出来ました。
今回は社員が複数の部署に属すという仕様で使いました。
テーブルは次のようにしました。
parts(部署テーブル)、
users(社員テーブル)、
parts_users(部署・社員連携テーブル)
部署・社員連携テーブルは繋げたいテーブルを「_」で連結させてテーブル名とします。
parts_usersのフィールドは「part_id、user_id」となります。
次にPartsUserモデルを作っていないとエラーになるので作っておきます。
class PartsUser extends AppModel { var $name = 'PartsUser'; var $useTable = 'parts_users'; }
Userモデルで
class User extends AppModel { var $name = 'User'; var $useTable = 'users'; var $hasAndBelongsToMany = array('Part'); }
と記述してあげるとUserモデルでセレクトして得られた配列に
所属している部署全てが取得できています。
データの取得はこれですんなりと上手くいったのですがデータの保存が
あまり資料が無くはまりました。
データをセレクトで取得した形式でsaveしてあげても上手く保存が出来ません。
ではどういう配列構造で保存してあげればいいのか、
$this->data['Part']['Part'][0] = 部署番号 $this->data['Part']['Part'][1] = 部署番号 $this->data['Part']['Part'][2] = 部署番号 ・ ・ ・
という感じにデータを持たしてあげるとparts_usersテーブルに社員と部署を
連携したデータを保存してくれます。
————————————————————–
↑↑↑↑↑↑↑↑↑↑↑ここまで前回の記事↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
————————————————————–
上記の方法で保存した時に実際の保存のSQLは下記のようになります。
UPDATE users SET name = '○○' WHERE users.id = 3; SELECT PartsUser.user_id FROM parts_users AS PartsUser WHERE PartsUser.user_id = 3; DELETE PartsUser FROM parts_users AS PartsUser WHERE PartsUser.user_id = (3); INSERT INTO parts_users (user_id,part_id) VALUES (3,17), (3,2);
これがCakePHPのバージョンが変わったところ、下記のようなSQLになってしまいます。
UPDATE users SET name = '○○' WHERE users.id = 3; SELECT PartsUser.part_id FROM parts_users AS PartsUser WHERE PartsUser.user_id = 3; DELETE PartsUser FROM parts_users AS PartsUser WHERE PartsUser.part_id = (17, 2); INSERT INTO parts_users (user_id,part_id) VALUES (3,17), (3,2);
このSQLだときちんと登録できないので、登録箇所はunbindModelをしてSQLを自分で作成することにしました。