使用html2canvas和jspdf加载SVG数据时出错

fdbelqdn  于 2022-12-16  发布在  其他
关注(0)|答案(2)|浏览(361)

我有一个非常简单的svg

<div id="printId">
    test
    <svg height="100" width="100">
        <circle cx="50" cy="50" r="40" />
    </svg> 
</div>

并尝试用html2canvas和jspdf打印它。但无论我做什么,我都会得到一个错误

Error loading svg data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%22100%22%20width%3D%22100%22%20style%3D%22-webkit-writing-mode%3A%20horizontal-tb%3B%20-webkit-user-modify%3A%20read-only%3B%20-webkit-user-drag%3A%20auto%3B%20-web
Oe.error @ html2canvas-1.1.2.min.js:20

以及其中只有单词testtest.pdf文件。
我在谷歌上搜索了大约3个小时,每个地方的人都推荐settings width/height atributes。正如你所看到的,这对我的情况没有帮助。我已经尽可能地简化了它。下面是我使用的完整的index.html:

<!DOCTYPE html>

<html>
    <head></head>
    <body>
    <div id="printId">
        test
        <svg height="100" width="100">
            <circle cx="50" cy="50" r="40" />
        </svg> 
    </div>

    <script src="../../../script/jsPDF/jspdf-2.3.1.umd.min.js" defer></script>
    <script src="../../../script/jsPDF/html2canvas-1.1.2.min.js" defer></script>
    <script>
        function saveAsPDF(divId, usersName, certNumber = '', type = 'old')
        {
        const { jsPDF } = window.jspdf;
        const pdf = new jsPDF();
        var source = document.getElementById("printId");

        pdf.html(
            source, {
            callback: function (pdf) {
                pdf.save("test.pdf");
            },
        });
        }
    </script>
    <input type='submit'
            onclick='saveAsPDF();'
            value='save'>
</body>
</html>

我也尝试了所有可能的html2canvas版本:
1.1.2
1.1.5
1.2.2
1.3.2
以及两个版本的JSPDF:
2.1.1
2.3.1
和两个浏览器:Chrome和Opera。
我有什么问题?
编辑:我通过下面的文档成功地让html2canvas独立工作,现在的问题是如何让它和jspdf一起工作:

<html>
    <head></head>
    <body>
            <div id="printId">
                this is circle:
            <svg height="100" width="100">
                <circle cx="50" cy="50" r="40" />
            </svg> 
            </div>
            <hr>
            <h4>Image of above HTML content...</h4>
            <div id="canvasImg"></div>

    <script src="../../../script/jsPDF/html2canvas-1.3.2.min.js"></script>
    <script>
        html2canvas(document.getElementById('printId')).then(function(canvas) {
            var canvasImg = canvas.toDataURL("image/jpg");
            document.getElementById('canvasImg').innerHTML = '<img src="'+canvasImg+'" alt="">';
        });
    </script>
</body>
</html>
7d7tgy0s

7d7tgy0s1#

看起来jspdf无法将svg作为矢量图形添加到页面中。有三个选项:
1.使用svg2pdf而不是jspdf将svg自己转换为pdf。
1.使用jspdf的addSvgAsImage函数在pdf页面中手动放置svg。
1.首先将svg转换为jpg,然后使用jspdf。
我选择了第三个选项并编写了一个函数,在将画布保存为pdf之前运行该函数:

htmlToJpg: function()
{
    var canvas = document.querySelector('.to-print');
    screenWidth = parseFloat(window.getComputedStyle(canvas).width);

    var problematic = document.querySelectorAll('.convert-to-jpg');
    problematic.forEach(function(el) {
        html2canvas(el, 
            {
                scale: 2480/screenWidth // 2480px - size for A4 paper, 300 dpi
            }
        )
        .then(function(canvas) {
            var img = canvas.toDataURL("image/jpeg");
            el.innerHTML = '<img src="' + img + '" class="img">';
        });
    });
}
t9eec4r0

t9eec4r02#

import html2canvas from 'html2canvas';
import { jsPDF as JsPDF } from 'jspdf';
import { useCallback, useEffect } from 'react';

export const useDownloadPdf = (name: string, isReady: boolean) => {
 useEffect(() => {
   if (isReady) {
    const fileName = `${name}.pdf`;
    const pdf = new JsPDF({
    orientation: 'p',
    unit: 'mm',
    format: 'a4',
    putOnlyUsedFonts: true,
    });

    const convertElements = document.querySelectorAll('.convert-on-pdf');
    const elements = Array.from(convertElements) as HTMLElement[];

    if (elements.length > 0) {
      Promise.all(
        elements.map(async (element) => {
          const canvas = await html2canvas(element);
          element.replaceWith(canvas);
      }),
      ).then(() => {
        pdf.html(document.body, {
          callback: (generatedPdf) => {
            generatedPdf.save(fileName)
          },
        });
      });
    } else {
      pdf.html(document.body, {
        callback: (generatedPdf) => {
        generatedPdf
          .save(fileName)
        },
      });
    }
  }
}, [isReady, name, setAtribute]);}

相关问题