安装
- yarn
yarn add @react-pdf/renderer
- npm
npm install @react-pdf/renderer --save
文档地址
使用
创建PDF文档
import React from "react";
import { Page, Text, View, Document, StyleSheet } from "@react-pdf/renderer";
// create style
const styles = StyleSheet.create({
page: {
backgroundColor: '#E4E4E4',
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
},
first: {
fontSize: 30,
fontFamily: 'pinru',
},
second: {
fontSize: 30,
fontFamily: 'FangSong',
lineHeight: 1.5,
},
});
// create document component
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #2</Text>
<Text>Section #2</Text>
</View>
</Page>
</Document>
)
export default MyDocument;
显示在页面上
import React from "react";
import MyDocument from './page';
import ReactPDF from "@react-pdf/renderer";
import { PDFViewer } from "@react-pdf/renderer";
function MyPDF () {
return (
<div>
<PDFViewer width={1200} height={950}>
<MyDocument />
</PDFViewer>
</div>
)
}
export default MyPDF;
常用的Components
Page
- size
设置pdf大小,支持传入height和width,也可以传入纸张类型(如:
A4
)
- wrap 是否允许换行
Text
- 用于显示文本, 支持内嵌Text或Link组件
View
- 基本视图组件
Styling
创建样式
import React from 'react';
import { StyleSheet } from '@react-pdf/renderer';
const styles = StyleSheet.create({
page: { backgroundColor: 'tomato' },
section: { color: 'white', textAlign: 'center', margin: 30 } });
使用
- 直接在同个文件中创建
- 也可以通过import引入进去
// index.js
import React from "react";
import { Page, Text, View, Document } from "@react-pdf/renderer";
import { styles } from './style';
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #2</Text>
<Text>Section #2</Text>
</View>
</Page>
</Document>
)
export default MyDocument;
// style.js
import { StyleSheet } from '@react-pdf/renderer';
export const styles = StyleSheet.create({
page: {
fontFamily: 'song',
lineHeight: 1.1,
letterSpacing: -1.5
}
});
内联多个样式
// index.js
import React from "react";
import { Page, Text, View, Document } from "@react-pdf/renderer";
const styles = StyleSheet.create({
page: {
backgroundColor: '#E4E4E4',
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
},
first: {
fontSize: 30,
fontFamily: 'pinru',
},
});
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style=[styles.section, styles.first, {color: '#eee'}]>
<Text>Section #2</Text>
<Text>Section #2</Text>
</View>
</Page>
</Document>
)
export default MyDocument;
字体引入
import { StyleSheet, Font } from "@react-pdf/renderer";
import Normal from '../font/fontfamily-normal.ttf';
import FangSongNormal from '../font/FangSong-normal.ttf';
// Register font
Font.register({ family: 'pinru', src: Normal });
Font.register({ family: 'FangSong', src: FangSongNormal });
const styles = StyleSheet.create({
first: {
fontSize: 30,
fontFamily: 'pinru',
},
second: {
fontSize: 30,
fontFamily: 'FangSong',
lineHeight: 1.5,
},
});
- 同种字体设置不同的字体属性
踩坑记
中文乱码
- 解决: 引入字体
import React from "react";
import { Page, Text, View, Document, StyleSheet, Font } from "@react-pdf/renderer";
import Normal from '../font/fontfamily-normal.ttf';
import FangSongNormal from '../font/FangSong-normal.ttf';
// Register font
Font.register({ family: 'pinru', src: Normal });
Font.register({ family: 'FangSong', src: FangSongNormal });
// create style
const styles = StyleSheet.create({
page: {
backgroundColor: '#E4E4E4',
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
},
first: {
fontSize: 30,
fontFamily: 'pinru',
},
second: {
fontSize: 30,
fontFamily: 'FangSong',
lineHeight: 1.5,
},
});
// create document component
const MyDocument = () => (
<Document>
<Page size={{width: '1200'}} style={styles.page}>
<View style={[styles.section, styles.first]}>
<Text>Section #1</Text>
<Text>春江潮水连海平,海上明月共潮生。</Text>
<Text>滟滟随波千万里,何处春江无月明!</Text>
<Text>江流宛转绕芳甸,月照花林皆似霰;</Text>
<Text>空里流霜不觉飞,汀上白沙看不见。</Text>
<Text>江天一色无纤尘,皎皎空中孤月轮。</Text>
<Text>江畔何人初见月?江月何年初照人?</Text>
<Text>人生代代无穷已,江月年年望相似。</Text>
<Text>不知江月待何人,但见长江送流水。</Text>
<Text>白云一片去悠悠,青枫浦上不胜愁。</Text>
<Text>谁家今夜扁舟子?何处相思明月楼?</Text>
<Text>可怜楼上月裴回,应照离人妆镜台。</Text>
<Text>玉户帘中卷不去,捣衣砧上拂还来。</Text>
<Text>此时相望不相闻,愿逐月华流照君。</Text>
<Text>鸿雁长飞光不度,鱼龙潜跃水成文。</Text>
<Text>昨夜闲潭梦落花,可怜春半不还家。</Text>
<Text>江水流春去欲尽,江潭落月复西斜。</Text>
<Text>斜月沉沉藏海雾,碣石潇湘无限路。</Text>
<Text>不知乘月几人归,落月摇情满江树。
</Text>
</View>
<View style={[styles.section, styles.second]}>
<Text>#中文通过空格换行#</Text>
<Text>仿宋是印刷字体的一种,仿照宋版书上所刻的字体,笔画粗细均匀,有长、方、扁三体,也叫仿宋体,仿宋字。</Text>
<Text>#有空格换行#</Text>
<Text>仿宋是印刷字体的一种,仿照宋版书上所刻的字体, 笔画粗细均匀,有长、方、扁三体,也叫仿宋体,仿宋字。</Text>
</View>
</Page>
</Document>
)
export default MyDocument;
中文字体不会自动换行
-
原因:react-pdf对中文换行处理很不友好,是根据段落中的空格去换行
-
解决:在两个字直接插入空格,实现自动换行
// 填充空格
function getBlankWord(word: string) {
return String(word).replace(/./g, (word) => word + ' ');
}
// 缩进字间距
function getWordStyle(fontSize) {
const letterSpacing = -fontSize / 3;
return {
letterSpacing
} as ReactPDF.Style;
}
<Text stlye={letterSpacing: getWordStyle(fontSize).letterSpacing}>{getBlankWord(works)} </Text>
可以基于<Text>
封装一个可以换行的文本组件<BlankText>
<View>
组件不能写文字,会报错
- 解决:文本用
<Text>
Error: Type mismatch
- 原因: 组件里面输入了文本
- 解决例子: github.com/diegomura/r…