More Related Content Similar to Excel2 canvas (14) More from Shunji Konishi (20) Excel2 canvas2. ExcelシートをWebブラウザ上に描画するライブ
ラリ
◦ https://github.com/shunjikonishi/excel2canvas
罫線や背景色はHTML5のCanvas上に描画
◦ なのでIE8以前の古いブラウザでは動きません
◦ 動作確認は一応Chrome, Firefox, IE9, Safari, iOS,
Androidでしてます。
特に何か目的を持って作ったものではなく、
Canvasの調査時になんとなく思いつきで試して
みたのが始まり
◦ 絵心があったら多分こんなものは作ってない。。。
3. ネットで拾ったもの
を少し加工したサン
プル(記憶が確かなら
一番最初のテスト
データ)
思った以上にExcel
で作ったレイアウト
を再現できてる
ちなみに印刷もこの
ままでます
さりげなく画像(左上
のロゴ)とリンクもサ
ポート
4. グラフも部分的
にサポート
棒グラフや円グ
ラフなどの単純
なグラフのみ
細かいプロパ
ティ設定は全部
無視するので見
た目はExcelと
同じにはならな
い
グラフの描画に
使用しているラ
イブラリは
Flotr2
5. まずJava側で
◦ Apache POIでExcelファイルの情報を読み取り
◦ それをJSON化
次にJavaScriptで
◦ キャンバスに罫線と背景を描画して
◦ 文字列はセル毎にdivタグで絶対位置に配置
◦ その上に画像とグラフを重ねて完成
とても泥臭い
6. ExcelToCanvasBuilder builder = new ExcelToCanvasBuilder();
builder.setIncludeComment(true);//コメント情報を含める
builder.setIncludeChart(true);//グラフ情報を含める
builder.setIncludePicture(true);//画像情報を含める
String json = builder.build(new File("Book1.xlsx"), "Sheet1").toJson();
ExcelToCanvasBuilderを作ってExcelファイルを
渡してやればOK
7. {"width":1035,"height":872,"lines":[{"p":[702,0,963,0],"kind":2},{"p":[0,32,224,32],"kind":6},{"p":[702,32,963,32],"kind":2},{"p":[0,52,688,52],"kind":2},{"p":[702,52,963,52]},{"p":[0,70,688
,70]},{"p":[702,70,963,70]},{"p":[702,88,963,88]},{"p":[0,106,688,106]},{"p":[702,106,963,106]},{"p":[0,125,688,125],"kind":2},{"p":[702,125,963,125]},{"p":[702,143,963,143]},{"p":
[0,162,688,162],"kind":2},{"p":[702,162,963,162]},{"p":[0,180,688,180]},{"p":[702,180,963,180]},{"p":[702,198,963,198]},{"p":[0,216,688,216]},{"p":[702,216,963,216]},{"p":[0,235,
688,235],"kind":2},{"p":[702,235,963,235]},{"p":[29,254,688,254],"kind":2},{"p":[702,254,963,254]},{"p":[0,273,688,273],"kind":2},{"p":[702,273,963,273]},{"p":[0,291,688,291]},{"p
":[702,291,963,291]},{"p":[0,309,688,309]},{"p":[702,309,963,309]},{"p":[0,327,688,327]},{"p":[702,327,963,327]},{"p":[0,345,688,345]},{"p":[702,345,963,345]},{"p":[0,363,688,36
3]},{"p":[702,363,963,363]},{"p":[0,381,688,381]},{"p":[702,381,963,381]},{"p":[0,399,688,399]},{"p":[702,399,963,399]},{"p":[0,417,688,417]},{"p":[702,417,963,417]},{"p":[0,435,6
88,435]},{"p":[702,435,963,435]},{"p":[0,453,688,453]},{"p":[702,453,963,453]},{"p":[0,471,688,471]},{"p":[702,471,963,471]},{"p":[0,489,688,489]},{"p":[702,489,963,489]},{"p":[0,
507,688,507]},{"p":[702,507,963,507]},{"p":[0,525,688,525]},{"p":[702,525,963,525]},{"p":[0,543,688,543]},{"p":[702,543,963,543]},{"p":[0,561,688,561]},{"p":[702,561,963,561]},{
"p":[0,579,688,579]},{"p":[702,579,963,579]},{"p":[0,597,688,597]},{"p":[702,597,963,597]},{"p":[0,615,688,615]},{"p":[702,615,963,615]},{"p":[0,634,688,634],"kind":2},{"p":[702,6
34,963,634]},{"p":[108,652,688,652]},{"p":[702,652,963,652]},{"p":[108,671,688,671],"kind":2},{"p":[702,671,963,671]},{"p":[108,689,688,689]},{"p":[702,689,963,689]},{"p":[108,
708,688,708],"kind":2},{"p":[702,708,963,708]},{"p":[108,727,688,727],"kind":2},{"p":[702,727,963,727]},{"p":[702,745,963,745]},{"p":[702,763,963,763]},{"p":[702,781,963,781]},
{"p":[702,799,963,799]},{"p":[702,817,963,817]},{"p":[702,835,963,835]},{"p":[702,854,963,854],"kind":2},{"p":[0,52,0,125],"kind":2},{"p":[0,162,0,235],"kind":2},{"p":[0,273,0,634],
"kind":2},{"p":[29,254,29,634],"kind":2},{"p":[108,52,108,125]},{"p":[108,162,108,235]},{"p":[108,254,108,634]},{"p":[108,634,108,727],"kind":2},{"p":[446,254,446,634]},{"p":[488,
254,488,634]},{"p":[568,254,568,727]},{"p":[688,52,688,125],"kind":2},{"p":[688,162,688,235],"kind":2},{"p":[688,254,688,727],"kind":2},{"p":[702,0,702,854],"kind":2},{"p":[756,0,
756,854]},{"p":[920,0,920,854]},{"p":[963,0,963,854],"kind":2}],"fills":[{"p":[702,0,54,32],"fore":"#C0C0C0"},{"p":[756,0,164,32],"fore":"#C0C0C0"},{"p":[920,0,43,32],"fore":"#C0C0
C0"},{"p":[29,254,79,19],"fore":"#969696"},{"p":[108,254,24,19],"fore":"#969696"},{"p":[132,254,92,19],"fore":"#969696"},{"p":[224,254,222,19],"fore":"#969696"},{"p":[446,254,42
,19],"fore":"#969696"},{"p":[488,254,80,19],"fore":"#969696"},{"p":[568,254,120,19],"fore":"#969696"},{"p":[0,273,29,18],"fore":"#969696"},{"p":[108,273,24,18],"fore":"#C0C0C0"}
,{"p":[132,273,92,18],"fore":"#C0C0C0"},{"p":[224,273,222,18],"fore":"#C0C0C0"},{"p":[488,273,80,18],"fore":"#C0C0C0"},{"p":[568,273,120,18],"fore":"#C0C0C0"},{"p":[0,291,29,1
8],"fore":"#969696"},{"p":[108,291,24,18],"fore":"#C0C0C0"},{"p":[132,291,92,18],"fore":"#C0C0C0"},{"p":[224,291,222,18],"fore":"#C0C0C0"},{"p":[488,291,80,18],"fore":"#C0C0C
0"},{"p":[568,291,120,18],"fore":"#C0C0C0"},{"p":[0,309,29,18],"fore":"#969696"},{"p":[108,309,24,18],"fore":"#C0C0C0"},{"p":[132,309,92,18],"fore":"#C0C0C0"},{"p":[224,309,222
,18],"fore":"#C0C0C0"},{"p":[488,309,80,18],"fore":"#C0C0C0"},{"p":[568,309,120,18],"fore":"#C0C0C0"},{"p":[0,327,29,18],"fore":"#969696"},{"p":[108,327,24,18],"fore":"#C0C0C0
"},{"p":[132,327,92,18],"fore":"#C0C0C0"},{"p":[224,327,222,18],"fore":"#C0C0C0"},{"p":[488,327,80,18],"fore":"#C0C0C0"},{"p":[568,327,120,18],"fore":"#C0C0C0"},{"p":[0,345,29,
18],"fore":"#969696"},{"p":[108,345,24,18],"fore":"#C0C0C0"},{"p":[132,345,92,18],"fore":"#C0C0C0"},{"p":[224,345,222,18],"fore":"#C0C0C0"},{"p":[488,345,80,18],"fore":"#C0C0
C0"},{"p":[568,345,120,18],"fore":"#C0C0C0"},{"p":[0,363,29,18],"fore":"#969696"},{"p":[108,363,24,18],"fore":"#C0C0C0"},{"p":[132,363,92,18],"fore":"#C0C0C0"},{"p":[224,363,22
2,18],"fore":"#C0C0C0"},{"p":[488,363,80,18],"fore":"#C0C0C0"},{"p":[568,363,120,18],"fore":"#C0C0C0"},{"p":[0,381,29,18],"fore":"#969696"},{"p":[108,381,24,18],"fore":"#C0C0C
0"},{"p":[132,381,92,18],"fore":"#C0C0C0"},{"p":[224,381,222,18],"fore":"#C0C0C0"},{"p":[488,381,80,18],"fore":"#C0C0C0"},{"p":[568,381,120,18],"fore":"#C0C0C0"},{"p":[0,399,2
9,18],"fore":"#969696"},{"p":[108,399,24,18],"fore":"#C0C0C0"},{"p":[132,399,92,18],"fore":"#C0C0C0"},{"p":[224,399,222,18],"fore":"#C0C0C0"},{"p":[488,399,80,18],"fore":"#C0C
0C0"},{"p":[568,399,120,18],"fore":"#C0C0C0"},{"p":[0,417,29,18],"fore":"#969696"},{"p":[108,417,24,18],"fore":"#C0C0C0"},{"p":[132,417,92,18],"fore":"#C0C0C0"},{"p":[224,417,2
22,18],"fore":"#C0C0C0"},{"p":[488,417,80,18],"fore":"#C0C0C0"},{"p":[568,417,120,18],"fore":"#C0C0C0"},{"p":[0,435,29,18],"fore":"#969696"},{"p":[108,435,24,18],"fore":"#C0C0
C0"},{"p":[132,435,92,18],"fore":"#C0C0C0"},{"p":[224,435,222,18],"fore":"#C0C0C0"},{"p":[488,435,80,18],"fore":"#C0C0C0"},{"p":[568,435,120,18],"fore":"#C0C0C0"},{"p":[0,453,
29,18],"fore":"#969696"},{"p":[108,453,24,18],"fore":"#C0C0C0"},{"p":[132,453,92,18],"fore":"#C0C0C0"},{"p":[224,453,222,18],"fore":"#C0C0C0"},{"p":[488,453,80,18],"fore":"#C0
C0C0"},{"p":[568,453,120,18],"fore":"#C0C0C0"},{"p":[0,471,29,18],"fore":"#969696"},{"p":[108,471,24,18],"fore":"#C0C0C0"},{"p":[132,471,92,18],"fore":"#C0C0C0"},{"p":[224,471,
222,18],"fore":"#C0C0C0"},{"p":[488,471,80,18],"fore":"#C0C0C0"},{"p":[568,471,120,18],"fore":"#C0C0C0"},{"p":[0,489,29,18],"fore":"#969696"},{"p":[108,489,24,18],"fore":"#C0C
0C0"},{"p":[132,489,92,18],"fore":"#C0C0C0"},{"p":[224,489,222,18],"fore":"#C0C0C0"},{"p":[488,489,80,18],"fore":"#C0C0C0"},{"p":[568,489,120,18],"fore":"#C0C0C0"},{"p":[0,507
,29,18],"fore":"#969696"},{"p":[108,507,24,18],"fore":"#C0C0C0"},{"p":[132,507,92,18],"fore":"#C0C0C0"},{"p":[224,507,222,18],"fore":"#C0C0C0"},{"p":[488,507,80,18],"fore":"#C0
C0C0"},{"p":[568,507,120,18],"fore":"#C0C0C0"},{"p":[0,525,29,18],"fore":"#969696"},{"p":[108,525,24,18],"fore":"#C0C0C0"},{"p":[132,525,92,18],"fore":"#C0C0C0"},{"p":[224,525,
222,18],"fore":"#C0C0C0"},{"p":[488,525,80,18],"fore":"#C0C0C0"},{"p":[568,525,120,18],"fore":"#C0C0C0"},{"p":[0,543,29,18],"fore":"#969696"},{"p":[108,543,24,18],"fore":"#C0C
0C0"},{"p":[132,543,92,18],"fore":"#C0C0C0"},{"p":[224,543,222,18],"fore":"#C0C0C0"},{"p":[488,543,80,18],"fore":"#C0C0C0"},{"p":[568,543,120,18],"fore":"#C0C0C0"},{"p":[0,561
,29,18],"fore":"#969696"},{"p":[108,561,24,18],"fore":"#C0C0C0"},{"p":[132,561,92,18],"fore":"#C0C0C0"},{"p":[224,561,222,18],"fore":"#C0C0C0"},{"p":[488,561,80,18],"fore":"#C0
C0C0"},{"p":[568,561,120,18],"fore":"#C0C0C0"},{"p":[0,579,29,18],"fore":"#969696"},{"p":[108,579,24,18],"fore":"#C0C0C0"},{"p":[132,579,92,18],"fore":"#C0C0C0"},{"p":[224,579,
222,18],"fore":"#C0C0C0"},{"p":[488,579,80,18],"fore":"#C0C0C0"},{"p":[568,579,120,18],"fore":"#C0C0C0"},{"p":[0,597,29,18],"fore":"#969696"},{"p":[108,597,24,18],"fore":"#C0C
0C0"},{"p":[132,597,92,18],"fore":"#C0C0C0"},{"p":[224,597,222,18],"fore":"#C0C0C0"},{"p":[488,597,80,18],"fore":"#C0C0C0"},{"p":[568,597,120,18],"fore":"#C0C0C0"},{"p":[0,615
,29,19],"fore":"#969696"},{"p":[108,615,24,19],"fore":"#C0C0C0"},{"p":[132,615,92,19],"fore":"#C0C0C0"},{"p":[224,615,222,19],"fore":"#C0C0C0"},{"p":[488,615,80,19],"fore":"#C0
C0C0"},{"p":[568,615,120,19],"fore":"#C0C0C0"},{"p":[108,671,24,18],"fore":"#C0C0C0"},{"p":[132,671,92,18],"fore":"#C0C0C0"},{"p":[224,671,222,18],"fore":"#C0C0C0"},{"p":[446,
671,42,18],"fore":"#C0C0C0"},{"p":[488,671,80,18],"fore":"#C0C0C0"},{"p":[568,671,120,18],"fore":"#C0C0C0"},{"p":[108,708,24,19],"fore":"#969696"},{"p":[132,708,92,19],"fore":"
#969696"},{"p":[224,708,222,19],"fore":"#969696"},{"p":[446,708,42,19],"fore":"#969696"},{"p":[488,708,80,19],"fore":"#969696"}],"strs":[{"p":[0,0,224,32],"id":"A1","text":"注 文 書
","align":"cb","style":"text-wrap:none;font-size:20pt;font-family:MS Pゴシック;"},{"p":[224,0,464,32],"id":"E1","text":" * 下の注文書に商品コードと数量をご記入、印刷の上、弊社担当
セールスにu003cbru003e お渡しいただくか、0xx-xxx-xxxx にファックスにてご送信ください。","align":"lb","style":"font-size:8pt;font-family:MS Pゴシッ
ク;"},{"p":[702,0,54,32],"id":"J1","text":"商品u003cbru003eコード","align":"cc","style":"font-size:10pt;font-family:MS Pゴシック;"},{"p":[756,0,164,32],"id":"K1","text":"商品名
","align":"cc","style":"text-wrap:none;font-size:10pt;font-family:MS Pゴシック;"},{"p":[920,0,43,32],"id":"L1","text":"価格","align":"cc","style":"text-wrap:none;font-size:10pt;font-
family:MS Pゴシック;"},{"p":[702,32,54,20],"id":"J2","text":"001-01","align":"lbg","style":"text-wrap:none;font-size:10pt;font-family:MS Pゴシック;"},…
8. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js“ ></script>
<link rel="stylesheet" type="text/css" media="screen,print" href="jquery.excel2canvas.css" />
<script type="text/javascript" language="javascript" src="flotr2.js"></script>
<script type="text/javascript" language="javascript" src="jquery.excel2canvas.min.js"></script>
<script type="text/javascript" language="javascript" src="jquery.excel2chart.flotr2.min.js"></script>
<script>
$(function() {
var data = ${excel.raw()};//さっきのJSONデータを埋め込む
$("#canvasHolder").excelToCanvas(data).css("width", $("#canvas").width());
});
</script>
...
<div id="canvasHolder">
<canvas id="canvas"></canvas>
</div>
jQueryプラグインになっているのでCanvasを保持す
るdivタグでexcelToCanvasメソッドを呼び出せばOK
9. 現状どれだけのことができるのか?
◦ 次ページ以降覚えてる範囲で実装内容を解説
◦ 言うまでもないが作ってないものは描画されない
この先どうなっていくのか?
◦ ぶっちゃけ未定
◦ ていうか最初に作ってから半年以上眠らせてたし。。。
◦ HerokuのAddonにする話が実現すれば状況は変わるか
な?
10. 必要なものから作る
◦ できることはわかっているが自分が使ってないので実装し
ていないものは結構ある
できそうなことはやる
◦ 需要があって実装が可能なものはできるだけやりたいと思
わないこともない
Excelのすべての機能を網羅することを目標としな
い
◦ 存在すら知らない機能が山ほどあるに違いない
◦ オブジェクトなどいかんともしがたいものはあきらめが肝
心
◦ ていうか多分想像できると思うけど本気でめんどくさ
い。。。(--
11. 罫線のスタイルは
POIで取得できてい
る
スクリプト側で厳密
に描画しているのは
以下
◦ 実線
◦ 二重線
◦ 破線
異なる長さのダッ
シュ線は単純な実線
として描画
◦ スクリプトの修正だけ
でできるわけだが。。。
12. 背景色、パターンの
色、パターンの種類、
すべてPOIで取得で
きている
しかし、スクリプト
側では単純に背景色
で塗りつぶしている
だけでパターンは無
視している
これもスクリプトの
修正だけでできるけ
ど、全部はやりたく
ない
13. 横位置は左詰め、右詰め、中央揃えに対応
◦ 均等割り付けはCSSで「text-align:jusify」を指定しているが
あんまり綺麗に表示されない
縦位置は上詰め、下詰め、中央揃えに対応
リッチストリング(単一セル内で文字の色や大きさを
変える)には未対応
セル全体のリンクには対応
折り返して全体を表示、縮小して全体を表示には未対
応
◦ 原則セルからはみ出す文字列は非表示
◦ ただし、左詰めで隣のセルが空いている場合はセルをはみ出
して文字列を表示
セルの結合には対応
14. Windows OS上のブラウザではOSにフォントがあればそれが使用される
MacはOSにあるフォントセットが全く違う上にfont-familyの日本語が不可なのでなんらかの
変換が必要
◦ とりあえずフォント名に「明朝」とか「ゴシック」とかがある場合は「serif」や「san-serif」を追加して
いる
◦ フォントがない場合はデフォルトのフォントで表示される
iOSとAndroidでは明朝フォントがそもそもない?のかほぼ常にゴシックで表示される。
15. POIの書式設定解釈は
日本語(特に日付関連)
がメタメタなので自力
でなんとかした
多分ほとんどの書式は
正確にでるはず
◦ 少なくとも日本語書式は
◦ 英語書式は多分大丈夫だ
けど他の言語?に関して
はデグレードしているか
もしれない
ただし先頭が「*」で
始まる書式はOSの情
報を使用しているので
サポートできない
16. Bootstrapの
tooltipで実装
このためだけ
にBootstrapを
includeするの
はイマイチな
ので実装変え
るかも
Bootstrapがな
い場合はコメ
ントは無視さ
れ、描画され
ない
17. なんとBASE64にしてJSONの中に突っ込んでいる
ちなみに描画は
◦ <img src=“data:image/jpeg;base64,… “/>
あまり大きな画像を貼り付けてはいけない
回転等には対応していない(CSS3ではできそうだけど。。。)
18. JavaScriptのグラフライブラリとしてはFlotr2を使用し以下に対
応
◦ 円グラフ
◦ 棒グラフ
◦ 折れ線グラフ
◦ レーダーチャート
細かいプロパティ設定等は考慮していない
◦ ので、見た目はExcel上で見た場合とは大分異なる
ちなみにグラフ情報はPOIでは取得できないのでOOXML直読
み。。。(--
単純なグラフでかつFlotr2が対応しているもの(例えばバブルグ
ラフとか)は今後サポートする可能性はあるが組み合わせグラフ
などにはおそらく対応しない。
JavaScriptライブラリは別のものに差し替えることができる設計
になっているが多分対応されることはない
◦ 最近は良さげなグラフライブラリがたくさんありすぎて何を使うのが良
いんだかよくわからない。。。
19. テストはほぼxlsxのみでxlsはほとんど試していない
◦ だいたいは正しく出力されると思うがグラフや画像は無視される
はず
◦ XlsはPOIのバグもあったような。。。
テーマを使用している場合の色が正しく取れない
◦ これはやり方がわからず色々なサイトを見て試行錯誤したあげく
あきらめた。(--
◦ ある程度近い色になる場合もあればまったく異なる色になること
もあってよくわからない。。。
Excelはデフォルトフォントによってセル幅の計算方法が
変わる
◦ これはセル幅を「デフォルトフォントで何文字分」という持ち方
をしているため。(なんで???)
◦ 「MS P ゴシック(日本語版)」と「Arial(多分英語版のデフォル
ト)」 には対応したけど、それ以外のデフォルトフォントではセ
ル幅が狂うと思われる。
クリップアート、その他の実装予定はない
20. 面倒なだけで特に難しいことはしていない
やろうと思えばできることはまだたくさんあるが。。。
◦ ただただめんどくさい
◦ マイナーな機能は使っている人が本当にいるのか謎(Excel職
人はいると思うけど)
◦ ほとんど使われることのない機能のためにスクリプトが肥大化
するのは避けたい
などの理由でもはや自分では優先順位がつけられない
(--
実際のところサポートしている機能はExcel機能のごく
一部でしかないが世の中のほとんどの人はその一部の
機能しか使っていないような気がする
◦ 今のままでもかなり使えるはず
◦ 後は必要に応じてかな。。。(^^;;;