最近要实现一个签合同的需要 须要前端实现合同展现、减少签名及公章、生成合同
诉求: 不容许用户随便更改复制文案
网上搜到的办法
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文档需要~