使用 jsPdf 将 html 转换为 pdf 不适用于 React 应用程序

发布于 2025-01-11 11:43:36 字数 1219 浏览 0 评论 0原文

我使用 React 作为前端应用程序,我想使用 jsPdf 将 React 组件的一部分导出为 pdf 文件。

const handleDownload = () => {
  const content = document.getElementById('download-content');
  const doc = new jsPDF();
  doc.html(content);
  doc.save("a4.pdf");
}

React 返回组件是:

return (
<body>
  <header id='download-content'>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
  </header>
  <footer>
    <button onClick={handleDownload}>Download</button>
  </footer>
</body>
)

单击 Download 按钮后,我想要一个 pdf 文件,其中包含带有样式的 header 标签数据。但在这里我用这个函数handleDownload得到了空白的pdf。

我不想使用canvas来生成图像然后制作pdf..如果我使用canvas,那么当页面大小最小化时pdf将会改变。

如何获得准确的 html 生成页面作为 pdf?

I am using react as a frontend application, I want to export a portion of react component as pdf file using jsPdf.

const handleDownload = () => {
  const content = document.getElementById('download-content');
  const doc = new jsPDF();
  doc.html(content);
  doc.save("a4.pdf");
}

React return component is:

return (
<body>
  <header id='download-content'>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
  </header>
  <footer>
    <button onClick={handleDownload}>Download</button>
  </footer>
</body>
)

After click on Download button I want a pdf file which consists header tag data with style. But here I got blank pdf with this function handleDownload.

I don't want to use canvas to generate image and then make pdf.. If I use canvas then, when page size minimize the pdf will change.

How can I get exact html generated page as pdf?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

咽泪装欢 2025-01-18 11:43:36

2 件事:

  1. 当在 React 中访问 DOM 元素时,你应该始终使用 useRef< /a>


  2. 看来 .html 方法是异步的并且需要回调

一个工作示例如下所示:

import { useRef } from 'react';
import { jsPDF } from 'jspdf';

export default function PDF() {
    const pdfRef = useRef(null);

    const handleDownload = () => {
        const content = pdfRef.current;

        const doc = new jsPDF();
        doc.html(content, {
            callback: function (doc) {
                doc.save('sample.pdf');
            }
        });
    };

    return (
        <div>
            <header ref={pdfRef}>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
            </header>
            <footer>
                <button onClick={handleDownload}>Download</button>
            </footer>
        </div>
    );
}

更新

如果您需要控制大小,可以按照上面引用的文档添加其他属性:

选项 1 - 使用 html2canvas 选项并控制规模:

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        html2canvas: { scale: 0.5 } // change the scale to whatever number you need
    });
};

选项 2 -使用 widthwindowWidth

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        width: 200, // <- here
        windowWidth: 200 // <- here
    });
};

2 Things:

  1. When getting access to a DOM Element in react you should always use useRef

  2. It appears that .html method is async and requires a callback

A working example would be something like this:

import { useRef } from 'react';
import { jsPDF } from 'jspdf';

export default function PDF() {
    const pdfRef = useRef(null);

    const handleDownload = () => {
        const content = pdfRef.current;

        const doc = new jsPDF();
        doc.html(content, {
            callback: function (doc) {
                doc.save('sample.pdf');
            }
        });
    };

    return (
        <div>
            <header ref={pdfRef}>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
            </header>
            <footer>
                <button onClick={handleDownload}>Download</button>
            </footer>
        </div>
    );
}

Update

If you need to control the size you can add additional properties as per documentation cited above:

Option 1 - use the html2canvas option and control the scale:

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        html2canvas: { scale: 0.5 } // change the scale to whatever number you need
    });
};

Option 2 - use width and windowWidth:

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        width: 200, // <- here
        windowWidth: 200 // <- here
    });
};
风吹雨成花 2025-01-18 11:43:36
// use can you ReactDOMServer.renderToString(element) 

import { renderToString } from "react-dom/server";
import { jsPDF } from "jspdf";
export const dow = () => {
  let htmlElement = <div>Hello </div> 
  let elementAsString = renderToString(htmlElement);
  var doc = new jsPDF();
  doc.html(elementAsString, {
    callback: function (doc) {
      doc.save("test.pdf");
    },
    x: 10,
    y: 10,
  });
};

// use can use this code as function to handle an event 
// use can you ReactDOMServer.renderToString(element) 

import { renderToString } from "react-dom/server";
import { jsPDF } from "jspdf";
export const dow = () => {
  let htmlElement = <div>Hello </div> 
  let elementAsString = renderToString(htmlElement);
  var doc = new jsPDF();
  doc.html(elementAsString, {
    callback: function (doc) {
      doc.save("test.pdf");
    },
    x: 10,
    y: 10,
  });
};

// use can use this code as function to handle an event 
情话难免假 2025-01-18 11:43:36

如果我正确理解了您的问题

这是我对您的问题的处理方法:

 const handleDownload = ()=>{
//content retrieves the element.
let content  = document.getElementById("download-content")
/*
 content2 retrieves the HTML code using ".outerHTML" as a string , 
 then add a line break between two opening tags, 
 as well as a line break between a closing tag and an opening tag 
 with the use of .replace and regexp
 */
let content2 = content.outerHTML.replace(/<(\w+)>(.*?)/g, '\n<$1>\n$2').replace(/(<\/\w+>)/g, '\n$1\n')
var doc = new jsPDF()
// This allows adding text to a PDF. 
doc.text(content2, 10 , 10)
doc.save("a4.pdf")

}

我希望此回复能够满足您的需求。

If I understood your question correctly

Here is my approach to your question:

 const handleDownload = ()=>{
//content retrieves the element.
let content  = document.getElementById("download-content")
/*
 content2 retrieves the HTML code using ".outerHTML" as a string , 
 then add a line break between two opening tags, 
 as well as a line break between a closing tag and an opening tag 
 with the use of .replace and regexp
 */
let content2 = content.outerHTML.replace(/<(\w+)>(.*?)/g, '\n<$1>\n$2').replace(/(<\/\w+>)/g, '\n$1\n')
var doc = new jsPDF()
// This allows adding text to a PDF. 
doc.text(content2, 10 , 10)
doc.save("a4.pdf")

}

I hope this response meets your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文