React-pdf: How do get blob data of pdf?

Created on 25 Jun 2020  路  12Comments  路  Source: diegomura/react-pdf

I'm trying to use the BlobProvider to get the blob data:

MyDocument = () => {
        return (
            <Document>
                <Page size="A4" style={stylez.page}>
                    <View style={stylez.section}>
                        <Text>Section TesterYo</Text>
                    </View>
                    <View style={stylez.section}>
                        <Text>Section #2</Text>
                    </View>
                </Page>
            </Document>
        )
    }

 LoadPdf = () => {
        let myPdf = <BlobProvider document={this.MyDocument()}/>
        var file = new File([myPdf], 'filename.pdf', { type: 'application/pdf', lastModified:Date.now()});


        this.setState({ files: [...this.state.files, file] }, () => console.log(this.state))
 }

This does not return MyDocument

Any insight on this would be appreciated

Most helpful comment

@brvnonascimento I've found in 2.0 beta I am able to call "updateContainer" to populate the pdf and avoid the errors you mentioned.

const doc = <Document></Document>;
const blobPdf = await pdf(doc);
blobPdf.updateContainer(doc);
const result = await pdf.toBlob();

I am curious though how are you offloading the process to a web worker? Would you mind giving an example of how you would do this?

All 12 comments

Hi @buzztnt

let blobPDF = pdf(this.MyDocument()).toBlob();

carefull it's a promise

const myfunction = async () => {
    let blobPDF = await pdf(this.MyDocument()).toBlob();
}

Code SandBox for my error:
https://codesandbox.io/s/distracted-boyd-po4xy?file=/src/App.js

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

const NewDocument = () => {
  return (
      <Document>
          <Page size='A4' >
              <View>
                  <Text>Hello</Text>
              </View>
          </Page>
      </Document>
  )
}

const OtherFC = () => {
   const getPdfBlob = async () =>   {
       let blobPdf = await pdf(NewDocument()).toBlob();

       console.log(blobPdf);
   }

   return(
     <button onClick={getPdfBlob}>Hello</button>
   )
}

When I try the example above it crashes with the following error:

react-pdf.browser.es.js:4251 Uncaught (in promise) TypeError: Cannot read property 'slice' of undefined
    at fetchAssets (react-pdf.browser.es.js:4251)
    at _pipe.js:3
    at _pipe.js:3
    at _arity.js:10
    at resolveAssets (react-pdf.browser.es.js:4293)
    at _callee$ (react-pdf.browser.es.js:6844)
    at tryCatch (runtime.js:45)
    at Generator.invoke [as _invoke] (runtime.js:274)
    at Generator.prototype.<computed> [as next] (runtime.js:97)
    at asyncGeneratorStep (asyncToGenerator.js:3)
fetchAssets @ react-pdf.browser.es.js:4251
(anonymous) @ _pipe.js:3
(anonymous) @ _pipe.js:3
(anonymous) @ _arity.js:10
resolveAssets @ react-pdf.browser.es.js:4293
_callee$ @ react-pdf.browser.es.js:6844
tryCatch @ runtime.js:45
invoke @ runtime.js:274
prototype.<computed> @ runtime.js:97
asyncGeneratorStep @ asyncToGenerator.js:3

That refers to this function in the module:

var fetchAssets = function fetchAssets(node) {
  var promises = [];
  var listToExplore = node.children.slice(0); //this line right here make it crash

  while (listToExplore.length > 0) {
    var _node = listToExplore.shift();

    if (isImage(_node)) {
      promises.push(fetchImage(_node));
    }

    if (_node.style && _node.style.fontFamily) {
      promises.push(Font$1.load(_node.style));
    }

    if (typeof _node === 'string') {
      promises.push.apply(promises, fetchEmojis(_node));
    }

    if (typeof _node.value === 'string') {
      promises.push.apply(promises, fetchEmojis(_node.value));
    }

    if (_node.children) {
      _node.children.forEach(function (childNode) {
        listToExplore.push(childNode);
      });
    }
  }

  return promises;
};

@brvnonascimento I have the same error.

I faced the same problem.
I solved it by changing the version from 2.0.0-bata.6 to 1.6.9.

I tried that but I get error "Uncaught Error: Type mismatch"

Downgrading to 1.6.9 made possible to get the blob data, that way I managed to parallelize the process to a Web Worker so it's non UI-blocking and really fast! The only downside is that not everything that is supported on beta2.0 is on 1.6.9, so one of my PDFs is basically broken, so a fix for this would be a life saver!

My bad, I'm using react-pdf V1.6.9 too

Should this become an issue "Imperative Blob Data doesn't work on beta2.0"?

@brvnonascimento I've found in 2.0 beta I am able to call "updateContainer" to populate the pdf and avoid the errors you mentioned.

const doc = <Document></Document>;
const blobPdf = await pdf(doc);
blobPdf.updateContainer(doc);
const result = await pdf.toBlob();

I am curious though how are you offloading the process to a web worker? Would you mind giving an example of how you would do this?

@rmathis Wow, it worked beautifully! I'll be posting a repo here with my Webpack config and all the caveats as a working example with WebWorkers.

Thank you, @rmathis for this amazing solution. I was banging my head to get a workaround this. But I am also anticipating this might break when there's an appropriate fix in the latest beta version.

The pdf function seems to be calling it itself anyway, I suspect its just extra call that may be unnecessary.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kishaningithub picture kishaningithub  路  4Comments

benbenedek picture benbenedek  路  3Comments

yellowBanano picture yellowBanano  路  3Comments

redcranesolutions picture redcranesolutions  路  4Comments

serkyen picture serkyen  路  4Comments