I have the following structure on a page:
export default function FichaTecnica(props) {
const data = props.data;
return (
<>
<Container>
<TopData info={data} />
<DataSheet datasheet={data} />
<GraphBox history={data} />
<MapButton hasMap={data.mapa} />
</Container>
</>
);
}
export async function getServerSideProps(context) {
const idIndicador = context.params.idIndicador;
const res = await fetch(
`${process.env.INDICADORES_BASE_URL}/indicadores/${idIndicador}`
);
const data = await res.json();
if (res.status === 200) {
return {
props: { ...data },
};
} else {
return {
props: {
data: [],
},
};
}
}
Inside the custom component "" I have a a list of buttons to export the information of the page as Excel, Json, CSV and PDF. I've already done the first three buttons, but I don't know where to start to export my page as PDF.
The idea is to export it as it is, meaning that I want to have it with the same style it has with CSS and the Material UI components, for example, if the website looks like this:
The PDF file should look like that, I know I can make it a Canva and make something like Html > img > PDF but I want to allow the user to select the text of the page in the PDF.
I would really appreciate if you can give me ideas to start with!
I have the following structure on a page:
export default function FichaTecnica(props) {
const data = props.data;
return (
<>
<Container>
<TopData info={data} />
<DataSheet datasheet={data} />
<GraphBox history={data} />
<MapButton hasMap={data.mapa} />
</Container>
</>
);
}
export async function getServerSideProps(context) {
const idIndicador = context.params.idIndicador;
const res = await fetch(
`${process.env.INDICADORES_BASE_URL}/indicadores/${idIndicador}`
);
const data = await res.json();
if (res.status === 200) {
return {
props: { ...data },
};
} else {
return {
props: {
data: [],
},
};
}
}
Inside the custom component "" I have a a list of buttons to export the information of the page as Excel, Json, CSV and PDF. I've already done the first three buttons, but I don't know where to start to export my page as PDF.
The idea is to export it as it is, meaning that I want to have it with the same style it has with CSS and the Material UI components, for example, if the website looks like this:
The PDF file should look like that, I know I can make it a Canva and make something like Html > img > PDF but I want to allow the user to select the text of the page in the PDF.
I would really appreciate if you can give me ideas to start with!
Share Improve this question asked Jan 31, 2022 at 19:46 Miguel VMiguel V 7422 gold badges8 silver badges26 bronze badges2 Answers
Reset to default 11Utilizing the puppeteer on the server side could be a good option.
One could create an API in nextjs to generate the PDF and pass back to the client. Something like below should be a good starting point:
import { NextApiRequest, NextApiResponse } from 'next';
import puppeteer from 'puppeteer';
const saveAsPdf = async (url: string) => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {
waitUntil: 'networkidle0'
});
const result = await page.pdf({
format: 'a4',
});
await browser.close();
return result;
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
const { url } = req.query; // pass the page to create PDF from as param
res.setHeader(
'Content-Disposition',
`attachment; filename="file.pdf"`
);
res.setHeader('Content-Type', 'application/pdf');
const pdf = await saveAsPdf(url as string);
return res.send(pdf);
};
Note: the server has to have Chromium browser version compatible with puppeeter.
There are couple of ways to do this
- An NPM Server side module - more options potentially
- Client side PDF object formation, lots of challenges - client side dependencies
- Use a service - cost
For #1 - try something like - https://www.npmjs.com/package/html-pdf?activeTab=readme
For #2 - https://github.com/parallax/jsPDF
For #3 - https://www.htmlpdfapi.com/