最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Error loading svg data with html2canvas and jspdf - Stack Overflow

programmeradmin1浏览0评论

I have a very simple svg

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

and trying to print it with html2canvas and jspdf. But whatever I do I get an error

Error loading svg data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3%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

and test.pdf file with just word test in it.

I googled this for about 3 hours, and in every place people remend settings width/height atributes. Which, as you can see, doesn't help in my case. I've simplified it as much as I could. Here is the full index.html I use:

<!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>

I also tried all possible versions of html2canvas:
1.1.2
1.1.5
1.2.2
1.3.2

and two versions of jspdf:
2.1.1
2.3.1

And two browsers: Chrome and Opera.

What can be my issue?

Edit: I managed to make html2canvas work on it's own with the document below. Now the question is how to make it work with jspdf together:

<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>

I have a very simple svg

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

and trying to print it with html2canvas and jspdf. But whatever I do I get an error

Error loading svg data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3%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

and test.pdf file with just word test in it.

I googled this for about 3 hours, and in every place people remend settings width/height atributes. Which, as you can see, doesn't help in my case. I've simplified it as much as I could. Here is the full index.html I use:

<!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>

I also tried all possible versions of html2canvas:
1.1.2
1.1.5
1.2.2
1.3.2

and two versions of jspdf:
2.1.1
2.3.1

And two browsers: Chrome and Opera.

What can be my issue?

Edit: I managed to make html2canvas work on it's own with the document below. Now the question is how to make it work with jspdf together:

<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>
Share Improve this question edited Oct 8, 2021 at 10:51 klm123 asked Oct 8, 2021 at 9:56 klm123klm123 12.9k14 gold badges64 silver badges107 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

It looks like jspdf is not able to add svg as vector graphic to a page. There are three options:

  1. Use svg2pdf instead of jspdf to convert svg to pdf on it's own.
  2. Use addSvgAsImage function of jspdf to place an svg in the pdf page manually.
  3. Convert svg to jpg first, then use jspdf.

I've chosen the 3rd option and wrote a function, which I run before saving canvas as 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">';
        });
    });
}
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]);}
发布评论

评论列表(0)

  1. 暂无评论