Skip to content

Instantly share code, notes, and snippets.

@JacobFischer
Created October 1, 2020 01:00
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save JacobFischer/aecbd871cb2aae46993236f65797da5c to your computer and use it in GitHub Desktop.
Save JacobFischer/aecbd871cb2aae46993236f65797da5c to your computer and use it in GitHub Desktop.
import React from 'react';
import {
pdf,
Document,
Page,
Text,
} from '@react-pdf/renderer';
import { saveAs } from 'file-saver';
const DocumentPdf = ({ someString }) => (
<Document>
<Page>
<Text>Hey look at this string: {someString}</Text>
</Page>
</Document>
);
const delay = (t) => new Promise((resolve) => setTimeout(resolve, t));
async function getProps() {
await delay(1_000);
return ({
someString: 'You waited 1 second for this',
});
}
export const LazyDownloadPDFButton = () => (
<button
onClick={async () => {
const props = await getProps();
const doc = <DocumentPdf {...props} />;
const asPdf = pdf({}); // {} is important, throws without an argument
asPdf.updateContainer(doc);
const blob = await asPdf.toBlob();
saveAs(blob, 'document.pdf');
}}
>
Download PDF
</button>
);
@muhammadhassan149
Copy link

Thank you.

@j0hj0h
Copy link

j0hj0h commented Oct 6, 2020

Thanks for the clean example. I had to pass an array in line 32, so changed it to const asPdf = pdf([]); ... before I got Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.

@layeng
Copy link

layeng commented Oct 15, 2020

Dear JacobFischer and jOhjOh,
thank you for your codes. Solve a big headache for me.

@chaofan232
Copy link

Thank you so much,JacobFischer . You saved my life. :)

@WeiTangLau
Copy link

WeiTangLau commented Jan 6, 2021

Awesome Stuff!
However, I am facing some problem with passing props to < DocumentPDF/ >
I am passing a list of objects as props. I will map each object to a < Text />. However, I am not getting anything. Any idea why?
@JacobFischer

@JacobFischer
Copy link
Author

I have not delved deep into @react-pdf/renderer in a few months, but last I used it there were a bunch of ways to pass perfectly valid looking props to @react-pdf/renderer/text components but they would render null anyways. My guess is that it's probably an issue with that library still.

@BakriSusanto
Copy link

Dear JacobFischer,

I am facing error when try to convert from .jsx to .tsx in line 32.
const asPdf = pdf({});

Argument of type '{}' is not assignable to parameter of type 'ReactElement<DocumentProps, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)>'.
Type '{}' is missing the following properties from type 'ReactElement<DocumentProps, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)>': type, props, key

any suggestion.
Thanks

@JacobFischer
Copy link
Author

Dear JacobFischer,

I am facing error when try to convert from .jsx to .tsx in line 32.
const asPdf = pdf({});

Argument of type '{}' is not assignable to parameter of type 'ReactElement<DocumentProps, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)>'. Type '{}' is missing the following properties from type 'ReactElement<DocumentProps, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)>': type, props, key

any suggestion.
Thanks

My guess is @react-pdf/renderer's TS types have been updated since I wrote this gist, and the type signature for the pdf() constructor has changed. If you wish to "hack" a solution, you could always do an any cast (though it's dangerous as you are losing type safety in the future):

const asPdf = pdf({} as any); // {} is important, throws without an argument

It looks like it wants a DocumentProps typed object. I'd suggest looking at what expected key/values exist in DocumentProps and adding them to make TypeScript and @react-pdf/renderer happy, without hacks.

@BakriSusanto
Copy link

Thank you so much. It's work now. using
const asPdf = pdf([] as any);

@mhonjester
Copy link

Thank you so much. It's working.

@chaithanyasuraj7878
Copy link

Hi @JacobFischer
Im able to download PDF using your solution, but im not getting any data of images or text which i dynamically fetching to pdf it just shows empty
Any idea how to resolve this please

@gwvwl
Copy link

gwvwl commented Nov 29, 2022

Hello, please tell me what to transfer to asPdf.

@alirezakasirzare
Copy link

thanks a lot, thats work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment