如何使用jsPDF使图像适应页面宽度?

71

有没有办法解决这个问题? 我试过以毫米为单位设置宽度和高度。如何将其设置为全宽?


2
为什么不直接将宽度和高度以毫米为单位设置为与页面大小相同呢?标准纸张尺寸很容易获得,而且由于您知道页面的大小,因此您知道应该将图像制作多大。或者我可能漏掉了什么? - enhzflep
请查看此示例和使用 jsPDF 的自动宽度调整函数:http://www.freakyjolly.com/jspdf-multipage-example-generate-multipage-pdf-using-single-canvas-of-html-document-using-jspdf/ - Code Spy
19个回答

3

以上某些答案没有涵盖与html2canvas相关的响应式页面。如果您需要根据变化的元素尺寸调整图像大小,请使用以下代码:

html2canvas(input, { scrollY: -window.scrollY }).then((canvas) => {
  const imgData = canvas.toDataURL('image/jpeg');
  const pdf = new jsPDF('p', 'mm', 'a4');
  const imgProps = pdf.getImageProperties(imgData);

  // doc and image dimensions
  const pdfWidth = pdf.internal.pageSize.getWidth();
  const pdfHeight = pdf.internal.pageSize.getHeight();
  const imgWidth = imgProps.width;
  const imgHeight = imgProps.height;

  // claculating right scale to fit the page
  const scale = Math.max(pdfHeight / imgHeight, pdfWidth / imgWidth);
  const finalWidth = imgWidth * scale;
  const finalHeight = imgHeight * scale;
  const leftMargin = (pdfWidth - finalWidth) / 2;
  // add image with alias and compression of your choice
  pdf.addImage( imgData, 'PNG', leftMargin, 0, finalWidth, finalHeight, 'alias', 'FAST');
  pdf.save( 'report-name.pdf' );
});

也许应该使用 Math.min 而不是 Math.max? - Pavlo Maistruk

2
更好的解决方案是使用图像的宽高比来设置文档的宽度/高度。

var ExportModule = {
  // Member method to convert pixels to mm.
  pxTomm: function(px) {
    return Math.floor(px / $('#my_mm').height());
  },
  ExportToPDF: function() {
    var myCanvas = document.getElementById("exportToPDF");

    html2canvas(myCanvas, {
      onrendered: function(canvas) {
        var imgData = canvas.toDataURL(
          'image/jpeg', 1.0);
        //Get the original size of canvas/image
        var img_w = canvas.width;
        var img_h = canvas.height;

        //Convert to mm
        var doc_w = ExportModule.pxTomm(img_w);
        var doc_h = ExportModule.pxTomm(img_h);
        //Set doc size
        var doc = new jsPDF('l', 'mm', [doc_w, doc_h]);

        //set image height similar to doc size
        doc.addImage(imgData, 'JPG', 0, 0, doc_w, doc_h);
        var currentTime = new Date();
        doc.save('Dashboard_' + currentTime + '.pdf');

      }
    });
  },
}
<script src="Scripts/html2canvas.js"></script>
<script src="Scripts/jsPDF/jsPDF.js"></script>
<script src="Scripts/jsPDF/plugins/canvas.js"></script>
<script src="Scripts/jsPDF/plugins/addimage.js"></script>
<script src="Scripts/jsPDF/plugins/fileSaver.js"></script>
<div id="my_mm" style="height: 1mm; display: none"></div>

<div id="exportToPDF">
  Your html here.
</div>

<button id="export_btn" onclick="ExportModule.ExportToPDF();">Export</button>


2

这是我在Reactjs中实现的方法。

主要问题是比例和缩放。如果你快速执行window.devicePixelRatio,它的默认值为2,这导致了半个图像的问题。

const printDocument = () => {
  const input = document.getElementById('divToPrint');
  const divHeight = input.clientHeight
  const divWidth = input.clientWidth
  const ratio = divHeight / divWidth;

  html2canvas(input, { scale: '1' }).then((canvas) => {
    const imgData = canvas.toDataURL('image/jpeg');
    const pdfDOC = new JSPDF("l", "mm", "a0"); //  use a4 for smaller page

    const width = pdfDOC.internal.pageSize.getWidth();
    let height = pdfDOC.internal.pageSize.getHeight();
    height = ratio * width;

    pdfDOC.addImage(imgData, 'JPEG', 0, 0, width - 20, height - 10);
    pdfDOC.save('summary.pdf');   //Download the rendered PDF.
  })
}

我正在寻找的是 scale: '1'!谢谢。 - Nilay Mehta

1

我遇到了同样的问题,但是我用以下代码解决了它

html2canvas(body,{
                onrendered:function(canvas){
                    var pdf=new jsPDF("p", "mm", "a4");
                    var width = pdf.internal.pageSize.getWidth();    
                    var height = pdf.internal.pageSize.getHeight();
                    pdf.addImage(canvas, 'JPEG', 0, 0,width,height);
                    pdf.save('test11.pdf');
                }
            }) 

0
关键是让画布尽量接近所需尺寸。
const handleDownloadCertificate = async () => {
  const domElement = document.getElementById('certificate');

  if (domElement) {
    try {
      const canvas = await html2canvas(domElement, { scale: 2 });
      const imgData = canvas.toDataURL('image/png');

      const componentWidth = domElement.clientWidth;
      const componentHeight = domElement.clientHeight;

      const ratio = componentHeight / componentWidth;

      const width = 210; // in mm A4
      let height = 297; // in mm A4

      height = ratio * width;

      const pdf = new JSPDF('p', 'mm', [width, height]);

      pdf.addImage(imgData, 'JPEG', 0, 0, width, height);

      const fileName = getCertificateName({ course, name });
      
      pdf.save(`${fileName}.pdf`);
      
    } catch (error) {
      console.error('Error building PDF', error);
    }
  }
};

0
将PDF页面宽度更改为图像的尺寸,步骤如下:
const exportOrgChartPdfFormat = async (response) => {
  try {
    const blob = new Blob([response.data], { // response.data contains blob
      type: "image/png",
    });
    const reader = new FileReader();
    reader.onloadend = () => {
      const base64data = reader.result;
      const img = new Image();
      img.onload = function () {
        const imgWidth = this.width;
        const imgHeight = this.height;
        const pdf = new jsPDF(
          imgWidth > imgHeight ? "l" : "p",
          "pt",
          [imgWidth, imgHeight]
        );
        **pdf.internal.pageSize.width = imgWidth;**
        **pdf.internal.pageSize.height = imgHeight;**
        pdf.addImage(
          base64data,
          "PNG",
          0,
          0,
          imgWidth,
          imgHeight
        );
        pdf.save("export.pdf");
      };

      img.src = base64data;
    };
    reader.readAsDataURL(blob);
  } catch (e) {
    return e;
  }
};

0
当我使用dom-to-image和jsPDF一起工作时,我遇到了同样的问题。我有一个来自我的HTML的图像,它的尺寸完美地匹配我的A4 PDF,但是在下载PDF时,图像有点模糊。为了解决这个问题,我将图像的比例放大了一倍,然后将其调整到我的PDF尺寸,然后再生成。
 const generatePDFfromHTML = async (htmlContentId: string, outputPath: string) => {
    const input = document.getElementById(htmlContentId)
    const scale = 2

    if (!input) {
        console.error(`HTML element with ID ${htmlContentId} not found.`)
        return
    }

    const scaledWidth = input.offsetWidth * scale
    const scaledHeight = input.offsetHeight * scale

    try {
        const dataUrl = await domtoimage.toPng(input, {
            width: scaledWidth,
            height: scaledHeight,
            style: {
                transform: "scale(" + scale + ")",
                transformOrigin: "top left",
            },
        })

        const pdf = new jsPDF()

        const img = new Image()
        img.src = dataUrl

        img.onload = () => {
            const pdfWidth = pdf.internal.pageSize.getWidth()
            const pdfHeight = (img.height * pdfWidth) / img.width
            pdf.addImage(dataUrl, "PNG", 0, 0, pdfWidth, pdfHeight)
            pdf.save(outputPath)
        }
    } catch (error) {
        console.error("Error generating PDF:", error)
    }
}

-1
convertPhotoImageToPdf(imgPath){
   var doc = new jsPDF(undefined, null, null, true);
   var imgData = 'data:image/jpeg;base64,'+ imgPath;
   doc.addImage(imgData, 'JPEG',10,10,0,0,null,'FAST',0);
   //if want add one page 
   //doc.addPage()
   doc.save('testPdf.pdf')
}

-2
        var width = doc.internal.pageSize.width;    
        var height = doc.internal.pageSize.height;

4
请勿仅以代码作为答案,还需提供代码的解释说明它是如何解决问题的。带有解释的答案通常更有帮助,质量更高,并且更可能吸引点赞。 - Ran Marciano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接