Docs
PDF
Utils for PDF generation.
Installation
Install the following dependencies:
pnpm add @react-pdf
Create lib/pdf/pdf.tsx
import { Document, Page, View } from "@react-pdf/renderer";
export const Pdf = ({
children,
title,
padding = {
left: "2.2cm",
right: "2.2cm",
top: "1.69cm",
bottom: "1.69cm",
},
}: {
children: React.ReactNode;
title: string;
padding?: {
left?: string;
right?: string;
bottom?: string;
top?: string;
};
}) => {
return (
<Document title={title}>
<Page
size="A4"
style={{
fontFamily: "Helvetica",
paddingBottom: padding.bottom,
paddingTop: padding.top,
paddingLeft: padding.left,
paddingRight: padding.right,
}}
>
<View
style={{
display: "flex",
flexDirection: "column",
justifyContent: "flex-start",
}}
>
{children}
</View>
</Page>
</Document>
);
};
Create lib/pdf/utils.ts
import { renderToStream } from "@react-pdf/renderer";
export const streamToBuffer = async (
stream: NodeJS.ReadableStream,
): Promise<Buffer> => {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
stream.on("data", (data) => {
chunks.push(data as Buffer);
});
stream.on("end", () => {
resolve(Buffer.concat(chunks));
});
stream.on("error", reject);
});
};
export const generatePdfFromComponent = async (component: JSX.Element) => {
// convert react component to stream
const pdfStream = await renderToStream(component);
// create buffer from stream
const pdfBuffer = await streamToBuffer(pdfStream);
return pdfBuffer;
};
Usage in route handler
NOTE
If there is a TypeError: ba.Component is not a constructor error, replace @react-pdf/renderer in utils.ts with @joshuajaco/react-pdf-renderer-bundled.
PDF as instant download
export function GET() {
const pdfBuffer = await generatePdfFromComponent(<Pdf />);
const response = new Response(pdfBuffer);
response.headers.set("Content-Type", "application/pdf");
return response;
}