前言

最近看了Thoughworks 官网的能力雷达功能,如下图的页面,可以把页面的数据渲染到pdf并用于下载。作为一个Java程序员,这个功能引发了我的思考: 如何较低成本实现这个功能?

  • Java 可行吗? —— 可行,有api,但是github上没有star比较多的项目,自己封装底层操作pdf的api比较费劲。

  • 前端可行吗?

    • 考虑前端的初衷是因为前端已经拿到数据了,如果前端能够独立处理,就没必要把同样的数据再传到Java后端
    • github上搜了下 react-pdf ,star 还ok,看文档也很好懂,所以研究一下。
  • 从未用过react,实现前端导出pdf的功能,刚好作为一个探索的动机学习一下。值得注意的是,本文只是个demo,不要作为工程代码直接使用。

在这里插入图片描述

环境

  • node.js
  • yarn (可以使用npm安装,是Facebook自家的依赖工具)

步骤

1. 安装react脚手架

# i 是install 的缩写 -g表示全局安装
npm i create-react-app -g

2. 使用 create-react-app 创建项目 (首字母不要大写、不要使用特殊字符)

# cd 进你喜欢的目录
# react-staging 是项目名
create-react-app react-staging

3. 用 vscode 打开目录 react-staging

配置热更新插件
在这里插入图片描述

4. yarn 启动项目

# 进入react-staging目录
yarn start

弹出的窗口能看到react logo则环境ok

5. 参考 react-pdf readme加入依赖

react-pdf readme
注意,主页并没有给出下载按钮的示例,需要看步骤6

6. 结合 github readme 和官方文档产出 demo 代码

react-pdf 官方文档
关注并修改脚手架代码的三个文件

  • App.js
import './App.css';
import React from 'react';
// 引入的框架能力
import { Document, Page, Text, View, StyleSheet, PDFDownloadLink} from '@react-pdf/renderer';

// Create styles
const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
    backgroundColor: '#E4E4E4'
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1
  }
});

// Create Document Component
const MyDoc = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text>Section #1</Text>
      </View>
      <View style={styles.section}>
        <Text>Section #2</Text>
      </View>
    </Page>
  </Document>
);

// 该 App 组件与 index.js 中的 App绑定
// index.js 会经过webpack打包封装到bundle.js中,index.html 则会默认引入bundle.js
function App() {
  return (
    <div className="App">
      <PDFDownloadLink document={<MyDoc />} fileName="somename.pdf">
      {({ blob, url, loading, error }) => (loading ? 'Loading document...' : 'Download now!')}
    </PDFDownloadLink>
    </div>
  );
}

export default App;

  • index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
// 获取index.html 中的dom节点,并借React的能力渲染App组件
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

7. 启动项目查看效果

在这里插入图片描述
在这里插入图片描述

后记

已经证实将数据渲染到pdf上的需求是可行的,后续希望能慢慢解放后端服务的压力。并且,标签式的语句更能描述层次信息、样式信息。让pdf调整起来更方便更直观。另外react的虚拟dom还有webpack把index.js打包的细节都可以研究下,遇到问题再回过头来看看。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐