React 및 Puppeteer: PDF 생성(클라이언트 다운로드 및 인쇄)

15905 단어 puppeteenxpdreact

요약



이제 서버가 설정되었습니다. 이제 이 API를 사용할 수 있는 클라이언트와 모든 것을 하나로 묶을 것입니다.

설정 UI



1 단계



생성된 PDF의 인쇄 및 다운로드를 관리하는 몇 가지 후크를 만들어 보겠습니다.

다음 후크는 다음을 담당합니다.
  • pdf 서버측 생성
  • 추가 사용을 위해 blob url 생성 중

  • 나중에 Blob URL을 어떻게 사용할 수 있습니까?
  • PDF 인쇄하기
  • PDF 다운로드 중
  • 클라이언트에서 PDF 보기(아마도 iframe을 통해)

  • // file: apps/ui-app/src/app/hooks/use-generate-pdf-blob-url.ts
    
    import { useEffect, useState } from 'react';
    import { useDebouncedCallback } from 'use-debounce';
    import axios, { AxiosResponse } from 'axios';
    import { PDFDocumentData } from '@pdf-generation/constants';
    import { PdfDocProps } from '@pdf-generation/pdf-doc';
    import { pdfData } from '../app.constants';
    
    const generatePdfDocument = (data: PDFDocumentData<PdfDocProps>) => {
      return axios.post<
        PDFDocumentData<PdfDocProps>,
        AxiosResponse<{ data: number[] }>
      >('/api/pdf/generate', data);
    };
    
    export const useGeneratePDFBlobURL = ({ enabled = true } = {}) => {
      const [isGeneratingPdf, setIsGeneratingPdf] = useState(false);
      const [pdfBlobURL, setPdfBlobURL] = useState<string>();
      const [error, setError] = useState();
    
      const generatePdf = useDebouncedCallback(
        (data) => {
          generatePdfDocument(data)
            .then(({ data: pdfBufferData }) => {
              const blob = new Blob([new Uint8Array(pdfBufferData.data)], {
                type: 'application/pdf',
              });
              const blobURL = URL.createObjectURL(blob);
    
              setIsGeneratingPdf(false);
              setPdfBlobURL(blobURL);
            })
            .catch((generationError) => {
              setIsGeneratingPdf(false);
              setError(generationError);
            });
        },
        500,
        { maxWait: 2000 }
      );
    
      useEffect(() => {
        if (!pdfBlobURL && enabled) {
          generatePdf.cancel();
          setIsGeneratingPdf(true);
          generatePdf(pdfData);
        }
    
        return () => {
          if (pdfBlobURL) {
            URL.revokeObjectURL(pdfBlobURL);
          }
        };
      }, [generatePdf, pdfBlobURL, enabled]);
    
      return {
        isGeneratingPdf,
        pdfBlobURL,
        error,
      };
    };
    
    


    이 다음 후크는 Blob URL을 수락하는 데 사용할 수 있으며 PDF를 다운로드하는 작업으로 사용할 수 있습니다.

    // file: apps/ui-app/src/app/hooks/use-pdf-link-downloader.ts
    
    import { useCallback } from 'react';
    
    export const usePDFLinkDownloader = () => {
      const downloadPdf = useCallback((blobURL: string, fileName: string) => {
        const link = document.createElement('a');
        document.body.appendChild(link);
        link.setAttribute('style', 'display: none');
        link.href = blobURL;
        link.download = fileName;
    
        link.click();
    
        setTimeout(() => {
          document.body.removeChild(link);
        }, 300);
      }, []);
    
      return {
        downloadPdf,
      };
    };
    


    이 다음 후크는 Blob URL을 수락하는 데 사용할 수 있으며 PDF를 인쇄하는 작업으로 사용할 수 있습니다.

    // file: apps/ui-app/src/app/hooks/use-print-pdf.ts
    
    import { useCallback } from 'react';
    
    export const usePrintPDF = () => {
      const printPdf = useCallback((blobURL: string) => {
        const iframe = document.createElement('iframe');
        document.body.appendChild(iframe);
        iframe.style.display = 'none';
        iframe.src = blobURL;
        iframe.onload = function print() {
          setTimeout(() => {
            iframe.focus();
            iframe?.contentWindow?.print();
          }, 1);
        };
      }, []);
    
      return {
        printPdf,
      };
    };
    



    그게 다야!

    이제 원하는 대로 UI를 공식화할 수 있습니다.

    전체 솔루션을 보려면 repository을 참조하십시오.

    git clone https://github.com/lwhiteley/pdf-generation-experiment
    cd pdf-generation-experiment
    pnpm i
    pnpm nx run-many --target=serve --projects=pdf-server,ui-app
    


    이러한 명령을 실행한 후 앱을 사용하여 위에 나열된 작업을 수행할 수 있습니다.


    무엇 향후 계획?
  • 더 나은 페이지 나누기 관리
  • PDF/이미지 압축
  • 글꼴과 관련된 문제 탐색
  • 도커화
  • 좋은 웹페이지 즐겨찾기