【问题标题】:How to set image to fit width of the page using jsPDF?如何使用jsPDF将图像设置为适合页面的宽度?
【发布时间】:2016-07-28 02:14:47
【问题描述】:

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

【问题讨论】:

  • 为什么不简单地将宽度和高度(mm)设置为与页面大小(mm)相同?标准纸张尺寸很容易获得,并且由于您知道页面有多大,因此您知道要制作多大的图像。或者我错过了什么?
  • 检查这个例子和使用jsPDF的自动宽度调整功能freakyjolly.com/…

标签: javascript jspdf


【解决方案1】:

您可以像下面这样获取PDF文档的宽度和高度,

var doc = new jsPDF("p", "mm", "a4");

var width = doc.internal.pageSize.getWidth();
var height = doc.internal.pageSize.getHeight();

然后您可以使用此宽度和高度为您的图像以适合整个 PDF 文档。

var imgData = 'data:image/jpeg;base64,/9j/4AAQSkZJ......';

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

确保您的图像具有与 PDF 文档相同的大小(分辨率)。否则它看起来会变形(拉伸)。

如果您想将px 转换为mm,请使用此链接http://www.endmemo.com/sconvert/millimeterpixel.php

【讨论】:

  • 如何保证您的图像始终与页面/PDF 文档的大小/分辨率相同?更好的方法是计算图像的纵横比和页面的相对宽度/高度比。请参阅我的答案below
  • 如果要保持比例:``` var ratio = canvas.width/canvas.height; var 宽度 = doc.internal.pageSize.getWidth(); var 高度 = 宽度 / 比率; doc.addImage(imgData, 'PNG', 0, 0, 宽度, 高度); ```
  • 对于这个解决方案,即使它适合,但 pdf 页面最终会被扭曲。还是谢谢你
  • 我在使用html2canvas 方法缩放图像高度时遇到问题,此解决方案修复了它。为了使画布宽度适合 pdf,我使用了这种方法:html2canvas(pdfElement, { scrollY: -window.scrollY })。此外,通过addImage() 方法中的 x、y 值,您可以设置 pdf 内容在页面中的位置。
  • doc.internal.pageSize.getWidth();由于 getWidth() 不是函数而出现错误
【解决方案2】:

如果您需要获取 PDF 文件的 100% 宽度和 自动高度,您可以使用 html2canvas 库的getImageProperties 属性 p>

html2canvas(input)
      .then((canvas) => {
        const imgData = canvas.toDataURL('image/png');
        const pdf = new jsPDF({
          orientation: 'landscape',
        });
        const imgProps= pdf.getImageProperties(imgData);
        const pdfWidth = pdf.internal.pageSize.getWidth();
        const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
        pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
        pdf.save('download.pdf');
      });

【讨论】:

  • 嗯——我不记得在任何地方都提到过 html2canvas。但是......让我们面对现实吧,这正是我们大多数人正在做的事情,谢谢!
  • 如果我想添加另一个页面怎么办?
  • 唯一对我有用的解决方案,谢谢。
【解决方案3】:

我的回答涉及您所要求的更具体的情况,但我认为可以从中得出一些想法以更普遍地应用。另外,如果可以的话,我会将其作为评论发布到Purushoth 的答案(我的答案是基于此)。

好的,所以我的问题是如何在不丢失纵横比的情况下将网页放入 pdf 文档中。我将 jsPDF 与 html2canvas 结合使用,并根据div 的宽度和高度计算了比率。我将相同的比例应用于 pdf 文档,页面完美地贴合到页面上,没有任何失真。

var divHeight = $('#div_id').height();
var divWidth = $('#div_id').width();
var ratio = divHeight / divWidth;
html2canvas(document.getElementById("div_id"), {
     height: divHeight,
     width: divWidth,
     onrendered: function(canvas) {
          var image = canvas.toDataURL("image/jpeg");
          var doc = new jsPDF(); // using defaults: orientation=portrait, unit=mm, size=A4
          var width = doc.internal.pageSize.getWidth();    
          var height = doc.internal.pageSize.getHeight();
          height = ratio * width;
          doc.addImage(image, 'JPEG', 0, 0, width-20, height-10);
          doc.save('myPage.pdf'); //Download the rendered PDF.
     }
});

【讨论】:

  • 这种方法解决了我将大图像放入字母格式页面的问题。完全推荐它
【解决方案4】:

我今天早上在试验 html2canvas 时发现了这一点。虽然这不包括打印多页的规定,但它确实将图像缩放到页面宽度并根据调整后的宽度重新调整高度:

html2canvas(document.getElementById('testdiv')).then(function(canvas){
        var wid: number
        var hgt: number
        var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height);
        var hratio = hgt/wid
        var doc = new jsPDF('p','pt','a4');
        var width = doc.internal.pageSize.width;    
        var height = width * hratio
        doc.addImage(img,'JPEG',20,20, width, height);
        doc.save('Test.pdf');
    });

【讨论】:

  • 最佳答案。将图像大小固定为成比例的大小。
  • 这个效果很好,但是输出质量太低了。
【解决方案5】:

自从commit 之后,API 发生了变化,现在使用的是 1.4.1 版

var width = pdf.internal.pageSize.getWidth();
var height = pdf.internal.pageSize.getHeight();

【讨论】:

    【解决方案6】:

    如果您希望动态大小的图片尽可能地自动填充页面并仍保持图片的宽高比,您可以执行以下操作:

    let width = doc.internal.pageSize.getWidth()
    let height = doc.internal.pageSize.getHeight()
    
    let widthRatio = width / canvas.width
    let heightRatio = height / canvas.height
    
    let ratio = widthRatio > heightRatio ? heightRatio : widthRatio
    
    doc.addImage(
      canvas.toDataURL('image/jpeg', 1.0),
      'JPEG',
      0,
      0,
      canvas.width * ratio,
      canvas.height * ratio,
    )
    

    【讨论】:

    • 但图像看起来仍然像 iphone 一样在较小的屏幕尺寸下被拉伸。我们能做点什么吗?
    【解决方案7】:

    如果您只有一张图片,则很容易适应页面。更具挑战性的任务是将各种尺寸的图像放入 pdf 文件中。归档的关键是计算图像的纵横比和页面的相对宽度/高度比。以下代码是我用来在线将多张图像转换为 PDF 文件的代码。它将根据图像/页面的方向旋转图像并设置适当的边距。我的项目使用带有在线 src 的图像。您应该能够根据自己的需要进行修改。

    关于图片旋转,如果旋转后看到空白页,可能只是图片超出范围。有关详细信息,请参阅此answer

    function exportPdf(urls) {
        let pdf = new jsPDF('l', 'mm', 'a4');
        const pageWidth = pdf.internal.pageSize.getWidth();
        const pageHeight = pdf.internal.pageSize.getHeight();
        const pageRatio = pageWidth / pageHeight;
    
        for (let i = 0; i < urls.length; i++) {
            let img = new Image();
            img.src = urls[i];
            img.onload = function () {
                const imgWidth = this.width;
                const imgHeight = this.height;
                const imgRatio = imgWidth / imgHeight;
                if (i > 0) { pdf.addPage(); }
                pdf.setPage(i + 1);
                if (imgRatio >= 1) {
                    const wc = imgWidth / pageWidth;
                    if (imgRatio >= pageRatio) {
                        pdf.addImage(img, 'JPEG', 0, (pageHeight - imgHeight / wc) / 2, pageWidth, imgHeight / wc, null, 'NONE');
                    }
                    else {
                        const pi = pageRatio / imgRatio;
                        pdf.addImage(img, 'JPEG', (pageWidth - pageWidth / pi) / 2, 0, pageWidth / pi, (imgHeight / pi) / wc, null, 'NONE');
                    }
                }
                else {
                    const wc = imgWidth / pageHeight;
                    if (1 / imgRatio > pageRatio) {
                        const ip = (1 / imgRatio) / pageRatio;
                        const margin = (pageHeight - ((imgHeight / ip) / wc)) / 4;
                        pdf.addImage(img, 'JPEG', (pageWidth - (imgHeight / ip) / wc) / 2, -(((imgHeight / ip) / wc) + margin), pageHeight / ip, (imgHeight / ip) / wc, null, 'NONE', -90);
                    }
                    else {
    
                        pdf.addImage(img, 'JPEG', (pageWidth - imgHeight / wc) / 2, -(imgHeight / wc), pageHeight, imgHeight / wc, null, 'NONE', -90);
                    }
                }
                if (i == urls.length - 1) {
                    pdf.save('Photo.pdf');
                }
            }
        }
    }
    

    如果这有点难以理解,您也可以使用.addPage([imgWidth, imgHeight]),这样更直接。这种方法的缺点是第一页被new jsPDF()固定。详情请见this answer

    【讨论】:

      【解决方案8】:

      所有屏幕尺寸和动态方向的解决方案:

      import html2canvas from 'html2canvas'
      import jsPDF from 'jspdf'
      
      export default async function downloadComponentInPDF(Component: HTMLElement) {
        await html2canvas(Component).then((canvas) => {
          const componentWidth = Component.offsetWidth
          const componentHeight = Component.offsetHeight
      
          const orientation = componentWidth >= componentHeight ? 'l' : 'p'
      
          const imgData = canvas.toDataURL('image/png')
          const pdf = new jsPDF({
          orientation,
          unit: 'px'
        })
      
          pdf.internal.pageSize.width = componentWidth
          pdf.internal.pageSize.height = componentHeight
      
          pdf.addImage(imgData, 'PNG', 0, 0, componentWidth, componentHeight)
          pdf.save('download.pdf')
        })
      }
      

      【讨论】:

      • 唯一可以导出整个可滚动页面的解决方案。谢谢。
      • 这是一个极好的解决方案,谢谢。
      【解决方案9】:

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

      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>

      【讨论】:

        【解决方案10】:

        我遇到了同样的问题,但我用这段代码解决了

        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');
                        }
                    }) 
        

        【讨论】:

          【解决方案11】:

          这就是我在 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' 是我要找的!谢谢。
          【解决方案12】:

          我的解决方案是根据 pdf 方向和图像大小检查需要应用的比例(高度或宽度)。注意:如果不需要边距,请将边距设置为 0。

             const imgData = canvas.toDataURL("image/jpeg");
          
             const pdf = new jsPDF({
                 orientation: "portrait", // landscape or portrait
                 unit: "mm",
                 format: "a4",
             });
             const imgProps = pdf.getImageProperties(imgData);
             const margin = 0.1;
          
             const pdfWidth = pdf.internal.pageSize.width * (1 - margin);
             const pdfHeight = pdf.internal.pageSize.height * (1 - margin);
          
             const x = pdf.internal.pageSize.width * (margin / 2);
             const y = pdf.internal.pageSize.height * (margin / 2);
          
             const widthRatio = pdfWidth / imgProps.width;
             const heightRatio = pdfHeight / imgProps.height;
             const ratio = Math.min(widthRatio, heightRatio);
             
             const w = imgProps.width * ratio;
             const h = imgProps.height * ratio;
          
             pdf.addImage(imgData, "JPEG", x, y, w, h);
          

          【讨论】:

            【解决方案13】:

            那里有很多带有 .addImage 的解决方案,我尝试了很多,但都没有成功。 所以我找到了 .html() 函数,并在尝试了一些 html2canvas-scale-option 之后。 此解决方案不是通用解决方案,您必须调整比例以适合您的 pdf,但这是唯一适合我的解决方案。

            var doc = new jspdf.jsPDF({
                orientation: 'p',
                unit: 'pt',
                format: 'a4'
            });
            
            doc.html(document.querySelector('#styledTable'), {
                callback: function (doc) {
                    doc.save('file.pdf');
                },
                margin: [60, 60, 60, 60],
                x: 32,
                y: 32,
                html2canvas: {
                    scale: 0.3, //this was my solution, you have to adjust to your size
                    width: 1000 //for some reason width does nothing
                },
            });
            

            【讨论】:

              【解决方案14】:
              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')
              }
              

              【讨论】:

                【解决方案15】:

                上面的一些答案没有涵盖 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' );
                });
                

                【讨论】:

                  【解决方案16】:
                          var width = doc.internal.pageSize.width;    
                          var height = doc.internal.pageSize.height;
                  

                  【讨论】:

                  • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
                  猜你喜欢
                  • 1970-01-01
                  • 2014-08-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-04-11
                  • 2017-08-29
                  • 1970-01-01
                  相关资源
                  最近更新 更多