You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用jsPdf生成PDF时如何强制设置图片方向?

React项目中jsPdf生成PDF时图片方向异常的解决方案咨询

问题背景

我在React项目里用jsPdf把包含移动端拍摄的base64格式图片的HTML内容转成PDF,HTML里图片显示完全正常,但生成PDF后图片出现了各种方向旋转的问题。尝试过两种方法都没解决:

  • 用jsPdf的addImage手动添加图片,结果页面排版直接错乱;
  • 通过EXIF拿到了图片的正确方向,但发现html2canvas不支持transform: rotate()这个CSS属性,旋转效果无法被渲染到PDF里。

现在咨询两个问题:

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

问题解答

1. jsPdf/html2canvas强制设置图片方向的可行方案

核心思路是先在Canvas上预处理图片,把图片旋转到正确方向后再替换原元素,而不是依赖CSS transform(html2canvas对这类变换的渲染支持很差)。

步骤1:编写图片矫正函数

function fixImageOrientation(img) {
    return new Promise((resolve) => {
        EXIF.getData(img, function() {
            const orientation = EXIF.getTag(this, 'Orientation');
            // 正常方向直接返回
            if (!orientation || orientation === 1) {
                resolve(img);
                return;
            }

            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            const imgWidth = img.width;
            const imgHeight = img.height;

            // 根据EXIF方向值处理旋转
            switch(orientation) {
                // 180度旋转
                case 3:
                    canvas.width = imgWidth;
                    canvas.height = imgHeight;
                    ctx.rotate(Math.PI);
                    ctx.drawImage(img, -imgWidth, -imgHeight, imgWidth, imgHeight);
                    break;
                // 顺时针90度(对应Orientation=6)
                case 6:
                    canvas.width = imgHeight;
                    canvas.height = imgWidth;
                    ctx.rotate(Math.PI / 2);
                    ctx.drawImage(img, 0, -imgHeight, imgWidth, imgHeight);
                    break;
                // 逆时针90度(对应Orientation=8)
                case 8:
                    canvas.width = imgHeight;
                    canvas.height = imgWidth;
                    ctx.rotate(-Math.PI / 2);
                    ctx.drawImage(img, -imgWidth, 0, imgWidth, imgHeight);
                    break;
                default:
                    resolve(img);
                    return;
            }

            // 生成矫正后的图片
            const fixedImg = new Image();
            fixedImg.src = canvas.toDataURL('image/png');
            fixedImg.onload = () => resolve(fixedImg);
        });
    });
}

步骤2:在html2clone回调中替换原图片

修改onclone回调为异步函数,逐个替换图片:

html2canvas: {
    onclone: async function(doc) {
        const images = doc.querySelectorAll("img");
        for (const img of images) {
            const fixedImg = await fixImageOrientation(img);
            // 替换原图片,保留原有的class和样式
            fixedImg.className = img.className;
            fixedImg.style = img.style;
            img.replaceWith(fixedImg);
        }
    },
    // 其他配置...
}

这样处理后,html2canvas渲染的就是已经矫正方向的图片,生成PDF时就不会出现旋转异常了。


2. 可替代的库推荐

如果上述方案还是无法满足需求,可以试试这些兼容性更好的库:

  • pdfMake:无需依赖html2canvas,直接用JSON结构定义PDF内容,支持在添加图片时指定rotation参数控制方向,适合需要精确控制排版的场景。
  • wkhtmltopdf:基于WebKit的命令行工具,对CSS和图片EXIF的支持非常完善,能自动识别并处理图片方向。可以通过Node.js的child_process调用,适合复杂HTML转PDF的场景。
  • html-pdf:基于wkhtmltopdf的Node.js封装,使用更简便,对HTML/CSS的兼容性远优于jsPdf/html2canvas,大部分情况下能自动解决图片方向问题。

内容的提问来源于stack exchange,提问作者NinaNa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:05:21