diegomura / react-pdf

📄 Create PDF files using React
https://react-pdf.org
MIT License
14.46k stars 1.14k forks source link

Inject external PDFs into react-pdf document #735

Open dberringer opened 4 years ago

dberringer commented 4 years ago

Is your feature request related to a problem? Please describe. I have PDFs that are not generated by react-pdf. It would be cool if I could inject them into my react-pdf document.

Describe the solution you'd like Option 1: It would be cool if we could use the image component or a new PDF component that would add the PDF content but also allow me to add other react-pdf components to the page as well so react-pdf could add a header and footer(with correct page numbers) over the top of the injected PDF so it all looked like it belonged together. Option 2: Add a src attribute on the page component that could take a path or a base64 encoded file and just insert the pages raw. It wouldn't be quite as seamless as option 1 but still pretty cool.

Describe alternatives you've considered To my knowledge, the only way to do this today is to use some tool to convert the PDF pages to images and inject them that way. Either that or I would need to use another tool to merge these PDFs after being generated by react-pdf. The downside would be that the footer wouldn't be on the injected pdf pages.

Additional context I don't think so.

Smriti29 commented 4 years ago

Try the following code. It will allow you to render an external pdf along with displaying page numbers. I have used semantic-ui-react which can be removed. Please make sure you are keeping your pdf file in the public folder.

App.js import React from 'react'; import { Container, Header, Grid, Form } from 'semantic-ui-react'; import { Document, Page} from 'react-pdf';

class App extends React.Component {

state = { file: null, numPages: 0, pageNumber: 1 } onFileChange = (event) => { this.setState({ file: event.target.files[0] }); } onDocumentLoadSuccess = ({ numPages }) => { this.setState({ numPages }); } nextPage = () => { const currentPageNumber = this.state.pageNumber; let nextPageNumber; if (currentPageNumber + 1 > this.state.numPages) { nextPageNumber = 1; } else { nextPageNumber = currentPageNumber + 1; } this.setState({ pageNumber: nextPageNumber }); } render() { const { pageNumber, numPages } = this.state; return (


PDF Preview
Please select a file}> {this.state.file ?

Page {pageNumber} of {numPages}

: null}
);

} } index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import * as serviceWorker from './serviceWorker'; import { pdfjs } from 'react-pdf'; pdfjs.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js';

ReactDOM.render(, document.getElementById('root')); serviceWorker.unregister();

dberringer commented 4 years ago

Thanks for the post @Smriti29 but to be honest I'm not totally following the example. I'm trying to render an external PDF as part of my react-pdf render. I see you have the file attr on the document which isn't part of the react-pdf spec. Also, even if that works(and I haven't had a chance to test it yet) wouldn't it just render the external PDF. I would expect to inject the PDF at the page level or page component level not the document. Do you have a simple example of this working? i.e. Something like this:

<Document>
  <Page>
    <Text>This is a test page 1</Text>
  </Page>
  <Page file='/sample.pdf' />
  <Page>
    <Text>This is a test page 3</Text>
  </Page>
</Document>
regarde commented 4 years ago

I am also interested in this feature. Would be happy to test/explore any potential hacks/solutions.

diegomura commented 4 years ago

@regarde feel free to research about it! This has been asked before and I said that I didn't see myself working on this feature soon, since there are other things in the backlog before. Also, pdfkit does not support this right now which makes it even harder to add. I didn't see any lib JS lib that merges PDFs either. And even if there is, I'm concerned about how heavy that dependency would be. Anyways, would love to see any potential solution since I'm not close to having this feature on the lib

regarde commented 4 years ago

I found a few libs (hummus, pdf assembler, pdf-lib) that merge different files and generate a new one, but none that really combine multiple files in a viewer. The only way would be to loop through the pages of the additional pdf files through pdf.js and render them through canvas. For my specific use case, it was easier to convert existing pdf files and import them as images in react-pdf.

dberringer commented 4 years ago

@regarde ya, that seems to be the workaround for now, however, you obviously lose text searchability with this approach which is a bummer. We really just need a PDF iframe. I'll keep my eye out for some method for doing this as well.

zigoo commented 4 years ago

Any update on the topic of embedding external PDF under Document/> ?

acomito commented 3 years ago

For my specific use case, it was easier to convert existing pdf files and import them as images in react-pdf.

This is a decent solution for now

clement-faure commented 3 years ago

Any news about this issue ? What is a recommended solution to achieve that ? When converting a multi pages PDF to images, i will probably loose page notion.

vkmetyk commented 3 years ago

Maybe someone will find it useful now. You need to use pdfjs library. Here is simple example how to create function for joining several pdfs:

joinMultiple: async (pdfBuffers) => { let doc = new pdfjs.Document({ properties: { creator: 'name', producer: 'name' } }); pdfBuffers.forEach(({ buffer }) => { let extDoc = new pdfjs.ExternalDocument(buffer); doc.addPagesOf(extDoc); }); return doc.asBuffer(); },

oosswwaalldd commented 3 years ago

Maybe someone will find it useful now. You need to use pdfjs library. Here is simple example how to create function for joining several pdfs:

joinMultiple: async (pdfBuffers) => { let doc = new pdfjs.Document({ properties: { creator: 'name', producer: 'name' } }); pdfBuffers.forEach(({ buffer }) => { let extDoc = new pdfjs.ExternalDocument(buffer); doc.addPagesOf(extDoc); }); return doc.asBuffer(); },

Does this work clien-side? or server-side only?

keithhackbarth commented 3 years ago

I could be missing something but I believe that pdfkit does have an API for this. I believe the scope of work here would be to add an attachment type that would render this api https://pdfkit.org/docs/attachments.html

I would love for attachments to be added as core feature as I think its the key thing missing from this library. Happy to sponsor this feature financially, otherwise maybe I'll take a crack at it next time I have enough free time.

diegomura commented 3 years ago

@keithhackbarth thanks! Related to that: https://github.com/diegomura/react-pdf/commit/2a8152e66e02cf71406fb96e3c49642946a24be0

keithhackbarth commented 3 years ago

@diegomura - Wow, this is amazing! We will try it out in our next Sprint and let you know how it goes.

tocosastalo commented 2 years ago

@keithhackbarth Did you figure out how to use Attachment?

ajitbohra commented 2 years ago

@tocosastalo it's not yet supported check this https://github.com/diegomura/react-pdf/issues/1443#issue-960894332

you can use react-pdf to generate the initial pdf and use pdf-lib to add attachments to it. Both the libraries work well together.

sourabhnegi1 commented 2 years ago

how can I add a pdf through a link inside a pdf I m creating through react-pdf/renderer

daredevil1302 commented 5 months ago

Are there any advancements or approved solutions to this? I need to attach .pdf to the PDF I'm generating using react-pdf/renderer. It should not be an image but a real pdf where the text can be selected

daredevil1302 commented 5 months ago

Are there any advancements or approved solutions to this? I need to attach .pdf to the PDF I'm generating using react-pdf/renderer. It should not be an image but a real pdf where the text can be selected

@diegomura I will assume that this downvote means there are no solutions at the moment :D

diegomura commented 5 months ago

Yes. It's not trivial to do so so it won't be something this lib will contain soon

goncalomano commented 3 months ago

Would also love to see this added.