从 html 生成 pdf 时如何设置/强制图像方向?

问题描述 投票:0回答:1

我正在使用 jsPdf 从 React 中的 HTML 输出生成 PDF。 HTML 包含移动设备拍摄的 Base64 图像。 在 HTML 中,它们可以正确显示,但在 PDF 中,它们会向各个方向旋转。 我尝试使用 jsPdf 函数手动添加图像,但页面流程不正确。

我也尝试过使用EXIF获取方向,这实际上是正确的,但似乎不支持transform:rotate() css。

  1. 使用jsPdf/html2canvas时有没有强制方向的方法?

  2. 有其他库可以用来解决问题吗?

     report.html(contentRef.current, {
             callback: function (doc) {
                 doc.setFontSize(8);
                 addGeneratedBy(doc);
                 addFooters(doc);
                 report.save(fileName);
                 setGenerating(false);
             },
             html2canvas: {
                 onclone: function (doc, element) {
                     let images = doc.querySelectorAll("img");
                     let targetRect = contentRef.current.getBoundingClientRect();
                     // 1: Normal (0° rotation)
                     // 3: Upside-down (180° rotation)
                     // 6: Rotated 90° counterclockwise (270° clockwise)
                     // 8: Rotated 90° clockwise (270° counterclockwise)
                     images.forEach((img) => {
                         let rect = img.getBoundingClientRect();
                         EXIF.getData(img, function () {
                             const orientation = EXIF.getTag(this, "Orientation");
                             console.log(orientation);
                             let deg = 0;
                             orientation == 3 && (deg = 180);
                             orientation == 6 && (deg = 270);
                             orientation == 8 && (deg = 90);
                             img.style.transform = `rotate(${deg}deg)`
                             //report.addImage(img, "PNG", 200, rect.y - targetRect.y, 100, rect.width, undefined, undefined, deg);
                             //img.remove();
    
                         });
                         // img.remove();
                     });
                 },
                 onrendered: function (canvas) {
                 }
             },
             margin: [95, 30, 30, 30],
             autoPaging: 'text',
             width: 500,
             y: 470,
             windowWidth: 1200
         });
    
reactjs jspdf html2canvas
1个回答
0
投票

https://artskydj.github.io/jsPDF/docs/module-addImage.html

(内部)addImage(imageData,格式,x,y,宽度,高度,别名, 压缩、旋转)

在您使用该策略时的评论尝试中,我看到您使用了以下方法:

report.addImage(
    img,                    //imageData
    "PNG",                  //format
    200,                    //x
    rect.y - targetRect.y,  //y
    100,                    //width
    rect.width,             //height
    undefined,              //alias
    undefined,              //compression
    deg                     //rotation
);

由于您在评论中说过自动生成的元素与图像位置不同步,因此您可能只是以错误的方式处理位置和大小,值得尝试一种准确的方法。

所以请尝试用以下内容更改该部分:

const imgData = img.src; // Get base64 data of the image
const imgWidth = rect.width;
const imgHeight = rect.height;
const posX = rect.x - targetRect.x; // X position relative to the contentRef
const posY = rect.y - targetRect.y; // Y position relative to the contentRef

// Add the image to the PDF
doc.addImage(
    imgData, //here I'm using the base64 data instead of the element itself (not needed but worth trying)
    "PNG", 
    posX,
    posY,
    imgWidth,
    imgHeight,
    undefined,
    "FAST", // Use compression for performance
    deg
);

请让我知道它是否有任何区别。如果它不起作用,我真的应该删除给出的答案。

这是完整的代码:

report.html(contentRef.current, {
    callback: function (doc) {
      doc.setFontSize(8);
      addGeneratedBy(doc);
      addFooters(doc);
      report.save(fileName);
      setGenerating(false);
    },
    html2canvas: {
      onclone: function (doc, element) {
        let images = doc.querySelectorAll("img");
        let targetRect = contentRef.current.getBoundingClientRect();
  
        images.forEach((img) => {

            // Position of the image relative to the container
            let rect = img.getBoundingClientRect();
              
            EXIF.getData(img, function () {
                const orientation = EXIF.getTag(this, "Orientation");
                
                let deg = 0;
                orientation == 3 && (deg = 180);
                orientation == 6 && (deg = 270);
                orientation == 8 && (deg = 90);
    
                const imgData = img.src; // Get base64 data of the image
                const imgWidth = rect.width;
                const imgHeight = rect.height;
                const posX = rect.x - targetRect.x; // X position relative to the contentRef
                const posY = rect.y - targetRect.y; // Y position relative to the contentRef
    
                // Add the image to the PDF
                doc.addImage(
                    imgData,
                    "PNG", 
                    posX,
                    posY,
                    imgWidth,
                    imgHeight,
                    undefined,
                    "FAST", // Use compression for performance
                    deg
                );

                img.remove();
            });            
        });
      },
      onrendered: function (canvas) {        
      },
    },
    margin: [95, 30, 30, 30],
    autoPaging: "text",
    width: 500,
    y: 470,
    windowWidth: 1200,
  });
© www.soinside.com 2019 - 2024. All rights reserved.