我正在使用 jsPdf 从 React 中的 HTML 输出生成 PDF。 HTML 包含移动设备拍摄的 Base64 图像。 在 HTML 中,它们可以正确显示,但在 PDF 中,它们会向各个方向旋转。 我尝试使用 jsPdf 函数手动添加图像,但页面流程不正确。
我也尝试过使用EXIF获取方向,这实际上是正确的,但似乎不支持transform:rotate() css。
使用jsPdf/html2canvas时有没有强制方向的方法?
有其他库可以用来解决问题吗?
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
});
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,
});