最近要实现一个签合同的需要 须要前端实现合同展现、减少签名及公章、生成合同
诉求: 不容许用户随便更改复制文案

网上搜到的办法
canvas生产pdf 但会呈现页面被截断状况,所以钻研了一下 react-pdf 和 @react-pdf/renderer,很好用~

@react-pdf/renderer
它会提供自带的元素,能够自定义款式,生成你想要的pdf

pdf内容

import { Document, Page, Text, StyleSheet, View, Image } from '@react-pdf/renderer';// 自定义字体 Font.register({  family: 'Oswald',   src: 'https://64a478.ttf' });const styles = StyleSheet.create({  body: {    paddingTop: 60,    paddingLeft: 40,    paddingRight: 40,    paddingBottom: 30,    fontFamily: 'Oswald'  },  title: {    fontSize: 14,    textAlign: 'center',    marginBottom: 30,  },  subtitle: {    fontSize: 14,    textAlign: 'center',    marginTop: 20,    marginBottom: 20,  },  introduce: {    fontSize: 12,    lineHeight: 1.6,  },  graph: {    fontSize: 12,    lineHeight: 1.6,    wrap: true,    fontWeight: 'thin',    color: 'rgba(0,0,0,.8)',  },  graphText: {    fontWeight: 'bold',    textDecoration: 'underline',    color: '#000',  },  signImg: {    width: '80px',    height: '80px',    position: 'absolute',    left: 0,    top: 0,    zIndex: 2  },  pageNumber: {    position: 'absolute',    fontSize: 12,    bottom: 30,    left: 0,    right: 0,    textAlign: 'center',    color: 'grey',  },});const Content = (name?: string) => {  return <Document>    <Page size="A4" style={styles.body} >      <Text style={styles.title}>BBBBB</Text>      <Text style={styles.introduce}>This Agreement.</Text>      <Text style={styles.subtitle}>AAAAAAa</Text>      <Text style={styles.graph}>        <Text style={styles.graphText}>加粗文案 </Text><Text>以后文案在一行内</Text>      </Text>      <Image            style={styles.signImg}            src="https:xxxxx.jpg"          />     {name ? <Text>{name}</Text> : <></>}      <Text style={styles.pageNumber} render={({ pageNumber, totalPages }) => (        `${pageNumber} / ${totalPages}`      )} fixed />    </Page>  </Document>}export default Content

pdf展现

  • hooks形式生成pdf连贯和blob文件

    import Content from './Content';const [instance] = usePDF({ document: Content('xiaoming') });// instance// loading/url/blob/error
  • DOM渲染
  • iframe形式展现,iframe底色无奈更改,对于款式要求较高的不太实用

    import { PDFViewer } from '@react-pdf/renderer';import Content from './Content';const App = () => (<PDFViewer>  <Content /></PDFViewer>);ReactDOM.render(<App />, document.getElementById('root'));
    react-pdf
    pdf链接渲染展现pdf,解决@react-pdf/renderer款式问题,能够通过第一种形式生成的blob地址或url渲染
    import React, { useState } from "react";import { Document, Page, pdfjs } from 'react-pdf';// 6版本会报错,且此办法无奈解决 须要应用5版本// "Error: Setting up fake worker failed: "Cannot read properties of undefined (reading 'WorkerMessageHandler')".pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;const PdfView = ({ url, loadSuccess, loadError }: any) => {const [numPages, setNumPages] = useState(null);function onDocumentLoadSuccess({ numPages: nextNumPages }: any) {  setNumPages(nextNumPages);  loadSuccess?.()}    // 页面会渲染2层  有一层的文案可被选中  css款式解决一下就好  // .react-pdf__Page__textContent {  //    display: none;  //  }return url ? <Document file={url} onLoadSuccess={onDocumentLoadSuccess} onLoadError={loadError} options={options} >  {Array.from(new Array(numPages), (el, index) => (    <Page className="contract-content-pdf-page" width={800} key={`page_${index + 1}`} pageNumber={index + 1} />  ))}</Document> : <></>}export default PdfView

这两个包联合应该能够实现不同场景不同需要的pdf文档需要~