shuding / nextra

Simple, powerful and flexible site generation framework with everything you love from Next.js.
https://nextra.site
MIT License
11.85k stars 1.28k forks source link

Need help with Export to PDF in Nextra #1560

Open luke-klein opened 1 year ago

luke-klein commented 1 year ago

Hey, I've been trying to implement the GitBook export as a PDF component, and I've tested a lot of libraries. Unfortunately, I haven't been able to implement it properly. I did find one library that works, but it doesn't create a proper PDF. Does anyone know of a better option, or is it possible to implement this feature by default in Nextra? Any help would be greatly appreciated!

GitBook image


My solution was

Here's the solution I've tried so far, including the PDFButton component and theme.config.tsx code:

PDFButton

import React, { useRef } from 'react';
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

const PDFButton = () => {
    const contentRef = useRef(null);

    const handleExportPDF = () => {
        const input = document.getElementById('pdf-content');
        html2canvas(input).then(canvas => {
            console.log(canvas); // log the canvas object
            const imgData = canvas.toDataURL('image/png');
            const pdf = new jsPDF({
                orientation: 'landscape',
                unit: 'px',
                format: [720, 720],
                compress: true,
            });
            pdf.addImage(imgData, 'PNG', 0, 0, 35, 420);
            pdf.save('export.pdf');
        });
    };

    return (
        <button
            onClick={handleExportPDF}
            className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        >
            Export as PDF
        </button>
    );
};

export default PDFButton;

theme.config.tsx

    main: ({ children }) => {
        return (
            <>
                <div id="pdf-content">{children}</div>
                <PDFButton />
                <BackToTop />
                <GiscusComments />
            </>
        );
    }

} as DocsThemeConfig

image

abhaytalreja commented 1 year ago

Are you trying to export just the single page or the entire book (docs)?

I have a solution I implemented for my other next.js project. I can try to create a PR. I am looking to create a export pdf for tall the pages as a book.

dionysuzx commented 1 year ago

+1 this would be so awesome

luke-klein commented 1 year ago

@abhaytalreja @d1onys1us @B2o5T @shuding

I have developed a solution that I believe will work for the entire project. This is the current version of my work. I would appreciate your feedback and suggestions on how to improve it or implement it in a better way.


  • PageWithExportButton.tsx
    
    import React, { useRef } from 'react';
    import html2canvas from 'html2canvas';
    import jsPDF from 'jspdf';

const PDFButton = () => { const contentRef = useRef(null);

const handleExportPDF = async () => {
    const input = document.getElementById('pdf-content');
    const canvas = await html2canvas(input, { scrollY: -window.scrollY });
    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF({
        orientation: 'portrait',
        unit: 'pt',
        format: [canvas.width, canvas.height],
        compress: true,
    });
    pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
    pdf.save('page.pdf');
};

return (
    <button
        onClick={handleExportPDF}
        className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
    >
        Export as PDF
    </button>
);

};

export default PDFButton;


> - **theme.config.tsx**
```tsx
import PDFButton from "@components/PdfExporter/PageWithExportButton";

     main: ({ children }) => {
        return (
            <>
                <div>{children}</div>
                <PageWithExportButton/>
                <BackToTop />
                <GiscusComments />
            </>
        );
    }
abhaytalreja commented 1 year ago

Few of issues:

  1. The button imported in the theme is PDFButton and the component your using is PageWithExportButton
  2. pdf-content where did you add this id? - Did you add it in index.tsx ?
  3. The styling on the button doesn't work on the default installing, i think we need to use nx-tailwind-class
amin-nas commented 8 months ago

@abhaytalreja any thing new to share on this? Thanks!