导出 PDF 图文报表实践

方法一: jsPDF

使用 jsPDF 时,需要注意的是其默认单位为 mm,需要在 new jsPDF() 时传入配置

const doc = new jsPDF({

unit: 'px',

format: 'a4'

})

这个方法废了。这个鬼东西多行文本和多个图片,简直要人命!

方法二: wkhtmltopdf

Vue SSR

使用 Vue.js ,需要 SSR 支持,否则页面为空白

使用 Nuxt.js 作为服务端渲染框架,这里记录一下遇到的问题和解决方案

1. 使用 Element UI,启动就报错 HTMLElement is not defined

pdf转html字符串 java pdf转成html_pdf转html字符串 java

Element UI 版本问题,使用最新的 2.8.x 会出现问题,则需要降版本并在 package.json 中配置版本策略,仅更新小版本范围

"element-ui": "~2.4.11",

2. JS的兼容问题

在使用 wkhtmltopdf 时,提示报错:Warning: http://localhost:3000/_nuxt/vendors.app.js:1941 SyntaxError: Parse error,估计是 ES6 的语法在wkhtmltopdf 的运行环境当中不支持,导致出现了这些错误提示。

pdf转html字符串 java pdf转成html_pdf转html字符串 java_02

官方Nuxt.js 2.6.X 版本其实给了 babel 的配置,默认会自动根据浏览器的运行环境做代码兼容,并不需要以下的这些设置(下面只是自己的实践过程,供参考),请直接使用第3点的解决方法。

通过查找资料,发现 Nuxt.js 并没有加入 Babel 进行 ES6 -> ES5 的转换,下面是解决方法

修改 nuxt.config.js,加入 babel-loader 相关配置

extend(config, ctx) {

// Run ESLint on save

if (ctx.isDev && ctx.isClient) {

config.module.rules.push(

{

enforce: 'pre',

test: /\.(js|vue)$/,

loader: 'eslint-loader',

exclude: /(node_modules)/

},

// 添加下方内容

{

test: /\.js$/,

loader: 'babel-loader',

exclude: /(node_modules)/

}

)

}

}

根目录加入 .babelrc 文件

{

"presets": [

[

"@babel/preset-env",

{

"useBuiltIns": "entry",

"corejs": "2",

}

]

],

"plugins": [

"@babel/plugin-syntax-dynamic-import"

]

}

以上设置完后,可能会提示以下类似的错误

ERROR in ./.nuxt/client.js

Module build failed (from ./node_modules/babel-loader/lib/index.js):

Error: Cannot find module 'babel-preset-env' from '/Users/wyj/Workspace/nuxt-example'

- Did you mean "@babel/env"?

at Function.module.exports [as sync] (/Users/wyj/Workspace/nuxt-example/node_modules/resolve/lib/sync.js:58:15)

at resolveStandardizedName (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/files/plugins.js:101:31)

at resolvePreset (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/files/plugins.js:58:10)

at loadPreset (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/files/plugins.js:77:20)

at createDescriptor (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-descriptors.js:154:9)

at items.map (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-descriptors.js:109:50)

at Array.map ()

at createDescriptors (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-descriptors.js:109:29)

at createPresetDescriptors (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-descriptors.js:101:10)

at presets (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-descriptors.js:47:19)

at mergeChainOpts (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-chain.js:320:26)

at /Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-chain.js:283:7

at buildRootChain (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/config-chain.js:120:22)

at loadPrivatePartialConfig (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/partial.js:85:55)

at Object.loadPartialConfig (/Users/wyj/Workspace/nuxt-example/node_modules/@babel/core/lib/config/partial.js:110:18)

at Object. (/Users/wyj/Workspace/nuxt-example/node_modules/babel-loader/lib/index.js:144:26)

根据错误提示,说明 babel-preset-env 还没有安装,命令行中执行相应的包,安装一下即可

yarn add @babel/preset-env core-js@2 -D

注意,这里的 corejs 版本为 2,使用 3 会出现以下错误

friendly-errors 01:38:28 ERROR Failed to compile with 35 errors

friendly-errors 01:38:28 These dependencies were not found:

friendly-errors 01:38:28

friendly-errors 01:38:28 * core-js/modules/es6.array.find in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.array.iterator in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.date.to-string in ./.nuxt/utils.js

friendly-errors 01:38:28 * core-js/modules/es6.function.name in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.object.assign in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.object.keys in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.object.to-string in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.promise in ./.nuxt/client.js

friendly-errors 01:38:28 * core-js/modules/es6.regexp.constructor in ./.nuxt/utils.js

3. Warning: undefined:0 TypeError: 'undefined' is not a function

在 nuxt.config.js 中加入兼容的 js 文件

head: {

// ...

script: [

{

src:

'https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.10/es5-shim.min.js'

},

{

src: 'https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js'

},

{

src:

'https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.3/es6-sham.min.js'

},

{

src:

'https://cdnjs.cloudflare.com/ajax/libs/es7-shim/6.0.0/es7-shim.min.js'

},

{

src:

'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.16.0/polyfill.min.js'

}

]

}

然后将代码打包出来再运行即可,就不会出现不兼容的问题了(注意,之前我用 yarn dev 运行,还是会出现第3点的错误,然而 generate 出来之后,就好了,估计webpack热更新里面的代码不兼容wkhtmltopdf的运行环境)

yarn generate

yarn start

运行 wkhtmltopdf 命令,开启 JavaScript 调试模式、延迟10秒保证页面接口请求完毕渲染完成

wkhtmltopdf --enable-javascript --debug-javascript --javascript-delay 10000 http://localhost:3000/echarts 1.pdf

最后的测试效果,图表和其他内容都呈现出来了

pdf转html字符串 java pdf转成html_html 转成pdf表格_03

静态HTML

最简单有效的方式,这里不做讨论。

参考资料

html转PDF文件,完美解决方案——jsPDF,htmltocanvas,pdfmake,wkhtmltopdf,TuesPechkin,snappy:

vue基于 html2canvas + jspdf 导出页面为PDF格式:https://www.bkbtp.com/38.html