質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.60%

画面のキャプチャからPDF化について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,947

score 200

参考
上記参考ページから、html2canvasとjsPDFを使用し、
画面のPDF出力を行っております。

動作としては問題なくいっているのですが、以下について教えて頂きたいです。
・デフォルトA4サイズでのPDF化をjsPDFは行いますが、画面がスクロールが必要なほど長い場合、複数ページにして全てを出力するにはどうすればいいでしょうか。
・cssなど意識せずとも画面の内容をキャプチャしPDF化してくれていますが、一部cssに崩れがあります。
どうも、A4のサイズに合わせたために横幅がギュッとなってるような感じなのですが、回避策などご存じないでしょうか。


>問題の再現ができないことには「崩れがある」「回避策はないか」と書かれても回答するために最も必要な情報がありません。
すいません、html文は載せることができません。
scriptは参考にしているところの通りです。
崩れがあるかどうか確認ではなく、使用されたことがある方で崩れた経験を持ち、
それを回避した経験がある方がいればと思い質問させて頂きました。

--
以下にサンプルコードを載せます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="html2canvas.min.js"></script>
<script>
    function downloadImage() {
        html2canvas(document.body).then(function(canvas) {
            var imgWidth = 210;
            var pageHeight = 295;
            var imgHeight = ((canvas.height) * imgWidth)/canvas.width;
            var heightLeft = imgHeight;
            var imgData = canvas.toDataURL('image/png');
            var doc = new jsPDF('p', 'mm');
            var position = 0;
            doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
            heightLeft -= pageHeight;
            while (heightLeft >= 0) {
                position = heightLeft - imgHeight;
                doc.addPage();
                doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
                heightLeft -= pageHeight;
            }
            doc.save('file.pdf');
        });
    }
</script>
<style>
    *{
        font-family:Geneva, Verdana, sans-serif;
    }
</style>
</head>
<body style="background-color:#EDF7FF;">
    <input id="downloadImageButton" type="button" value="画像保存" onclick="downloadImage();"/>
    <div style="width:910px">
        <table border="1" cellspacing="0" cellpadding="0" style="width:100%;text-align:center">
            <tr>
                <th style="width:40px">No.</th>
                <th style="width:80px"><a href="#">項目1</a></span></th>
                <th style="width:80px"><a href="#">項目2</a></span></th>
                <th style="width:80px"><a href="#">項目3</a></span></th>
                <th style="width:80px">項目4</th>
                <th style="width:80px">項目5</th>
                <th style="width:80px">項目6</th>
                <th style="width:80px">項目7</th>
                <th style="width:80px">項目8</th>
                <th style="width:80px">項目9</th>
            </tr>
            <tr>
                <td><label>1</label></td>
                <td><label>item1</label></td>
                <td><label>item2</label></td>
                <td><label>item3</label></td>
                <td><label>item4</label></td>
                <td><label>item5</label></td>
                <td><label>2019/04/01</label><br><label>2020/03/31</label></td>
                <td><label>ああああああああああああああああああああああああああああああ</label></td>
                <td><label></label></td>
                <td><a href="#">item6</a></td>
            </tr>
            <tr>
                <td><label>2</label></td>
                <td><label>item1</label></td>
                <td><label>item2</label></td>
                <td><label>item3</label></td>
                <td><label>item4</label></td>
                <td><label>item5</label></td>
                <td><label>2019/04/01</label><br><label>2020/03/31</label></td>
                <td><label>ああああああああああああああああああああああああああああああ</label></td>
                <td><label></label></td>
                <td><a href="#">item6</a></td>
            </tr>
        </table>
    </div>
</body>
</html>


例えば、これの場合FireFoxだと項目1~項目3のリンクの下線が文字に被っています。
また、項目6の日付が「~」とかぶってます。
IE11ではなぜか罫線が出ませんでした。
(それは本来のページでは起こっていませんので、cssの問題があるのだと思いますが。)
また、html2canvasは1.0.0-alpha12です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/02/05 15:05

    >上記参考ページから、html2canvasとjsPDFを使用し、
    画面のPDF出力を行っております。

    まず、ご自身のコードを提示してください。
    問題の再現ができないことには「崩れがある」「回避策はないか」と書かれても回答するために最も必要な情報がありません。

    キャンセル

  • m.ts10806

    2019/02/05 15:22

    なるほどそれなら仕方ないですね。
    「崩れ方は色々あって現象も原因も様々なのに再現確認できる情報なしにアドバイスしようがない」
    と感じる人が多数かと思いますが、がんばってください。

    キャンセル

  • 退会済みユーザー

    2019/02/05 17:49

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

checkベストアンサー

0

参考サイトをのコードを使って、縦長ページを全て出力できるように改造してみました。

function downloadImage() {
    html2canvas(document.body, {
        onrendered: function(canvas) {

            //PDF用意して
            var pdf = new jsPDF();
            //横幅と
            var width = pdf.internal.pageSize.width;
            //高さを取る
            var height = pdf.internal.pageSize.height;

            //ページ画像の横幅を取って
            var canvas_width = canvas.width;
            //横の縮小率を確認。
            var rate = canvas_width > width ? width / canvas_width : canvas_width / width;

            //縮小率を使って、PDFに埋め込んだ場合の高さを算出
            var just_canvas_height = canvas.height * rate;

            //埋め込み画像の高さを超えるまで、ページの追加と、画像の貼り付けを繰り返す
            var setheight = 0;
            while(setheight < just_canvas_height){
                if(setheight > 0){//2ページ目以降だけページ追加
                  pdf.addPage();
                }
                //画像の貼り付けの「y」の位置をずらします
                pdf.addImage(canvas, 'JPEG', 0, setheight*-1, width, 0);

                //1ページ分追加
                setheight += height;
            }
            //保存
            pdf.save('test.pdf');
        }
    });
}

ページの画像の高さからほぼぴったりで計算しているので、
当然、HTML内の文字や画像が横半分になって、2ページにまたがったりします。。

HTML内の画像は仕方ないとしても、文字はそれだと読めないので問題かなぁと思ったりしましたが、そこらへんは、フォントサイズとかを考えての調整かと思うので、お任せしますね。

A4のサイズに合わせたために横幅がギュッとなってる

というのが、私の適当に作ったテストページと、参考サイトをのコードでは再現できなかったので、そちらについてはわかりません。。。

mts10806さんがコメントされているように、「崩れ方は色々あって現象も原因も様々」です。
HTMLは全てではなくてもいいので、「ギュッとなってる」のを再現できる程度の最低限のHTMLとcssを提示できませんか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/06 16:03

    回答ありがとうございます。
    こちらの方でも調べて同じようなやり方で複数ページは出力できるようになりましたが、FireFoxの場合に途中で切れてしまっており全てが出力出来ておらず、その辺は継続調査中です。。。
    また、崩れの件は一旦サンプルを作成しましたので、質問に載せます。
    (途中で崩れるのは再現出来ていません、、)

    キャンセル

  • 2019/02/06 17:19

    >A4のサイズに合わせたために横幅がギュッとなってる
    これについては、どうやらcssがちゃんと当たってなさそうです。
    全てのcssがあたってないわけではなくfont-sizeをcssファイルでsmallにしていますが、
    それだけが当たってないように見えており、タグに直接style=の形で記入するとあたっております。

    キャンセル

  • 2019/02/07 10:34

    私が確認している現象とは違うのでしょうかね・・??
    cssファイルでfont-size:small;を指定してみましたが、ブラウザ上でも、PDFにもきちんと反映されていましたよ。

    こちらで確認する限り、横幅がぎゅっとなってしまう原因は、
    var imgHeight = ((canvas.height+701) * imgWidth)/canvas.width;
    この計算式のimgHeightを指定していることのように思うのですが、これはどのような意図で計算・指定されているのでしょうか?

    キャンセル

  • 2019/02/08 09:28

    >var imgHeight = ((canvas.height+701) * imgWidth)/canvas.width;
    申し訳ありません、式としては提示頂いたスクリプトと同じで、比率を考慮した高さなんですが、
    「701」の数値はテストで入れただけであり、本来は
    var imgHeight = ((canvas.height+701) * imgWidth)/canvas.width;
    でした、すいません。
    ただ、現象は発生しなかったというところで何かほかに考慮があるのかもしれません。
    現状はfirefoxでのみ崩れるので一旦この回答をベストアンサーとさせて頂いて、もう少しこちらで調査してみます。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る