前回の記事(印刷ボタンで特定の範囲を印刷するjQuery)の続きです。
前回の検証結果から「印刷ボタンで特定の範囲を印刷するjQuery」は特定の範囲の「HTMLソース」を抜き出して印刷するのではないかと推測されます。
ということは「印刷範囲のソース内にCSSも記述してあれば、Webサイトの見た目通りに印刷できる」のでは?と考えました。
前回のHTMLソースにCSSを書き込み印刷ボタンから印刷してみる
まずは簡単に、そのままCSSを読み込む記述を追加してみます。HTMLコーディングルールとしてはイマイチよろしくありませんが、「HTMLソースを抜き出して印刷している」という部分の検証になります。
印刷範囲内のHTMLソースにCSSを記述
外部ファイルCSSとは背景画像のパスが変更になるので注意です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<body> <header> ヘッダーエリア </header> <section id="printarea"> <!-- StyleSheet --> <style scoped> section { display: block; background: #CCC url("common/images/recipe_contents.gif") repeat-y 50% 0; width: 641px; margin: 0 auto; padding: 0 30px; overflow: hidden; } section div { width: 50%; height: 300px; float: left; } section div img { width: 200px; height: 150px; margin: 20px 40px; } section h1 { display: block; width: 100%; text-align: center; line-height: 2em; } </style> <!-- StyleSheet --> <div><img src="common/images/recipe01.png" alt="レシピ画像"></div> <div> <h1>レシピタイトル</h1> <h2>レシピ素材</h2> <ul> <li>お米・・・1合</li> <li>大根・・・1本</li> <li>人参・・・1本</li> <li>塩・・・少々</li> <li>味噌・・大さじ2</li> </ul> </div> <input type="button" id="btn_print" value="印刷する"> </section> <footer> フッターエリア </footer> </body> |
印刷してみる
早速印刷ボタンから印刷してみます。
・IE11の場合は [ページ設定]内の[背景の色とイメージを印刷する(C)]にチェックを
・FireFoxの場合は [ページ設定]内のオプション[背景色と背景画像も印刷]にチェックを
・Google Chromeの場合は [印刷プレビュー]の[+詳細設定]を開いて[背景のグラフィック]にチェックを
印刷結果→ダメでした
CSSが読み込まれている気配がありません。
追加調査
なんとかならないものか、スクリプトファイルの見直しからしてみます。
スクリプトファイルの中身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$.jPrintArea=function(el){ var iframe=document.createElement('IFRAME'); var doc=null; $(iframe).attr('style','position:absolute;width:0px;height:0px;left:-500px;top:-500px;'); document.body.appendChild(iframe); doc=iframe.contentWindow.document; var links=window.document.getElementsByTagName('link'); for(var i=0;i<links.length;i++) if(links[i].rel.toLowerCase()=='stylesheet') doc.write('<link type="text/css" rel="stylesheet" href="'+links[i].href+'"></link>'); doc.write('<div class="'+$(el).attr("class")+'">'+$(el).html()+'</div>'); doc.close(); iframe.contentWindow.focus(); iframe.contentWindow.print(); alert('Printing...'); document.body.removeChild(iframe); |
中をよくみると、9行目と10行目にCSSファイルを読み込んでいるような記述があります。
「type=”text/css”」記述が古そうなのでここを実際の記述にあわせてあげればいけるのでは?
しかもCSSをここで読んでくれているということは先程のHTML内のCSSも必要ないはずです。
つまり、前回と今回使用しているスクリプトはもとから印刷にCSSが反映されるようになっている。ということです。私がスクリプトの設置方法を間違っていただけでした。
加えてCSSの下のdivの記述も気になりますので、HTMLもあわせてみます。
sectionはCSSで使用しているので、一個外側をdivで囲ってみます。
スクリプトファイルとHTMLの修正
10行目type=”text/css”を取り記述をあわせてあげます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$.jPrintArea=function(el){ var iframe=document.createElement('IFRAME'); var doc=null; $(iframe).attr('style','position:absolute;width:0px;height:0px;left:-500px;top:-500px;'); document.body.appendChild(iframe); doc=iframe.contentWindow.document; var links=window.document.getElementsByTagName('link'); for(var i=0;i<links.length;i++) if(links[i].rel.toLowerCase()=='stylesheet') doc.write('<link rel="stylesheet" href="'+links[i].href+'"></link>'); doc.write('<div class="'+$(el).attr("class")+'">'+$(el).html()+'</div>'); doc.close(); iframe.contentWindow.focus(); iframe.contentWindow.print(); alert('Printing...'); document.body.removeChild(iframe); |
HTMLも変更します。38行目と39行目、もとはsectionにつけていたid=”printarea”をひとつ外側にdivで囲ってそのdivに対して指定しました。
最終的にHTMLは以下のようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <!-- disable iPhone inital scale --> <meta name="viewport" content="width=device-width"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>印刷ボタンで特定の範囲を印刷するjQuery</title> <!-- Keyword,Description --> <meta name="keywords" content="" > <meta name="description" content="" > <!-- StyleSheet --> <link rel="stylesheet" href="common/styles/style.css"> <!-- JQuery --> <script src="common/scripts/jquery.js"></script> <script src="common/scripts/print.js"></script> <script text="javascript/text"> $(function(){ $('#btn_print').click(function(){ $.jPrintArea("#printarea"); }); }); </script> </head> <body> <header> ヘッダーエリア </header> <div id="printarea"> <section > <div><img src="common/images/recipe01.png" alt="レシピ画像"></div> <div> <h1>レシピタイトル</h1> <h2>レシピ素材</h2> <ul> <li>お米・・・1合</li> <li>大根・・・1本</li> <li>人参・・・1本</li> <li>塩・・・少々</li> <li>味噌・・大さじ2</li> </ul> </div> <input type="button" id="btn_print" value="印刷する"> </section> </div> <footer> フッターエリア </footer> </body> </html> |
印刷結果は成功!
目的の部分だけ背景画像やCSSを読み込んだ形で印刷されています。
デモページをみる
※ Microsoft EdgeとGoogle Chromeの印刷に注意!
Window10のデフォルトブラウザのMicrosoft Edgeでは背景画像も印刷する設定がありません。公式でMicrosoftが「IE11で使えるのでそちらでお願いします。」とコメントしています。
また、「Google Chromeの場合は」と書きましたが、今回の件のような[印刷する]ボタンを押してからの印刷プレビューが真っ白で印刷出来ない方が多いようです。(メニューからの印刷では正常に印刷できます。)
私もそうでした。同系列のブラウザ「Vivaldi」でも同様でした。
拡張機能を全部消したり、ブラウザ設定の初期化をすると表示されるらしいので試してみましたが改善しませんでした。(ちゃんと印刷出来る人もいらっしゃるようです。)
まとめ
試行錯誤の結果、なんとか目的通りの形で印刷する事ができました。
今まではスクリプトファイルをネットで紹介されているものをそのまま試して使えたものだけ利用してきました。
今までそのまま使って動かなかったスクリプトもよく中身を調べたら動いていたことでしょう。
今後はスクリプトファイルの中身ももうちょっと良く調べてみようと思います。