2

我正在从 db 中搜索数据,结果以表格形式显示。然后用户可以下载任何记录的 pdf。我正在使用@react-pdf/renderer 库来生成 pdf,但这个库的问题是它生成所有结果的 pdf 一次。因此系统由于大量结果而挂起。我需要一个只为用户特定记录生成 pdf 的库,而不是一次全部生成。

下面是例子

import React, {useState} from 'react';
import { PDFDownloadLink, Document, Page,Text } from '@react-pdf/renderer'

const _data = [
    {
      name: 'Bi'
    },
    {
      name: 'Ars'
    },
    {
      name: 'Saee'
    }
]


const MyDoc = ({data}) => (
  <Document>
    <Page>
    <Text>{data.name}</Text>
    </Page>
  </Document>
)

const App = () => {
  const [data, setData] = useState(_data);
  const clickHandler = (key) => {
    return (
      <PDFDownloadLink document={<MyDoc  data={data[key]} />} fileName="somename.pdf">
        {({ blob, url, loading, error }) => (loading ? 'Loading document...' : url)}
      </PDFDownloadLink> 
    )
  }

  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>Sr</th>
            <th>Name</th>
          </tr>
        </thead>
        <tbody>
        {data.map((item, i) => {
          return (
              <tr key={i} onClick={() => clickHandler(i)}>
                <td>{i}</td>
                <td>{item.name}</td>
              </tr>   
          );
        })}
        </tbody>
      </table>
    </div>
)
  }

export default App;
4

2 回答 2

3

别担心。它有一个非常简单的解决方案,只需使用 npm react to pdf。

在你的项目中安装它

npm install react-to-pdf
import React from 'react';
import ReactTOPdf from "react-to-pdf";

const ref = React.createRef();
const PDF = (props) => {
  return (
    <>
      <div className="background_color" >
        <div className="pdf_container" ref={ref} style={{
          This should be your page what you want to make pdf.
        </div>
        <ReactTOPdf targetRef={ref} >
          {({ toPdf }) => 
            <button onClick={toPdf} className="get_started">
              Download
            </button>
          }
        </ReactTOPdf>
      </div>
    </>
  )
}

export default PDF;
于 2021-05-27T19:20:47.603 回答
1

好吧,我已经测试了你给我们的代码,它只获取与键对应的行,所以我认为这是预期的,但只返回一个 PDFDowloadLink 不起作用,因为它必须被渲染以允许用户点击它。

所以我认为你的问题是你想点击一行,生成一个链接来下载那个特定的行,而不是为每个行生成一个链接。

您可以通过在应用程序中添加另一个状态来做到这一点。

例如,如果您正在处理用户,您可以添加

const [user,setUser] = useState(null);

管理有关要转换为 PDF 的特定行的信息。

然后使用您的单击侦听器使用行信息修改用户状态,并在由条件管理的 DOM 中呈现链接(如果用户不为空,则显示链接)。

例如,如果你想在你的 App 方法中管理它,它可能是这样的:

const App = () => {
  const [data, setData] = useState(_data);
  const [user,setUser] = useState(null);
  const clickHandler = (key) => {
    setUser(data[key]);
  }

  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>Sr</th>
            <th>Name</th>
          </tr>
        </thead>
        <tbody>
        {data.map((item, i) => {
          return (
              <tr key={i} onClick={() => clickHandler(i)}>
                <td>{i}</td>
                <td>{item.name}</td>
              </tr>   
          );
        })}
        </tbody>
      </table>
      {data.map(value => console.log(value))}
          {user ? (<PDFDownloadLink document={<MyDoc  data={user} />} fileName="somename.pdf">
        {({ blob, url, loading, error }) => (loading ? 'Loading document...' :<a href={url}>Url Link here</a>)}
          </PDFDownloadLink>) : null}
    </div>
)
  }

希望这可以帮助。

于 2020-06-10T06:35:40.033 回答