2

I'm searching data from db and results displays in table form.Then user can download pdf of any record. I'm using @react-pdf/renderer library to generate pdf but problem with this library is that its generate pdf of all results once. therefore system hangs due to large number of result. I need a library which only generate pdf to user specific record not all at once.

below is example

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;

2 Answers 2

4

Don't worry about that. It has a very simple solution just using npm react to pdf.

install this in your project

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;
Sign up to request clarification or add additional context in comments.

Comments

1

Well i have tested the code you give to us, and it only fetch the row which corresponds to the key so i think this is as expected, but returning just a PDFDowloadLink doesn't work, because it has to be rendered to allow the user to click it.

So i think your problem is that you want to click on a row, generate a link to download just that specific row instead of generating a link for each one.

You may be able to do that by just adding another state in the App.

For example if you are handling users you can add

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

to manage the information about the specific row you want to convert to PDF.

Then use your click listener to modify the user state with the row information and render a link in the DOM managed by a condition (if the user is not null display a link).

for example, if you want to manage that in your App method, it may be something like this:

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

hope this helps.

1 Comment

Thanks Jason for your valuable answer. Actually this is not real code. I'll try this in real program and hopefully, this should work there. Your answer saves a lot of mine work. Once again Thank you :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.