Vue2.js:前端在浏览器中网页表格打印的实现方案:window.print、print-js、iframe

🎯 365bet官网网 📅 2025-07-17 19:50:26 👤 admin 👀 6204 ❤️ 336
Vue2.js:前端在浏览器中网页表格打印的实现方案:window.print、print-js、iframe

目录

需求描述方案1:直接打印页面方案2:使用css媒体查询控制打印内容方案3:第三方插件print-js方案4:将要打印的节点内容写入iframe方案5:将要打印的html写入iframe(推荐)

需求描述

最近有一个需求,是让用户通过浏览器可以打印表格内容

环境:

node v16.14.0vue2.jselement-ui

表格本身是使用了的el-table实现的,浏览器显示的时候很正常,没有什么异常。

创建vue2项目

$ node -v

v16.14.0

// 2022-10-14 最新版本 5.0.0

pnpm install -g @vue/cli

选择

- vue 2.6.14

- vuex 3.6.2

- vue-router 3.5.1

- less 4.0.0

表格数据 data.js

export const tableData = [

{

date: "2016-05-02",

name: "王小虎",

address: "上海市普陀区金沙江路 1518 弄",

},

{

date: "2016-05-04",

name: "王小虎",

address: "上海市普陀区金沙江路 1517 弄",

},

{

date: "2016-05-01",

name: "王小虎",

address: "上海市普陀区金沙江路 1519 弄",

},

{

date: "2016-05-03",

name: "王小虎",

address: "上海市普陀区金沙江路 1516 弄",

},

];

界面显示

直接ctrl+p 打印效果不是很好。于是,开始寻找解决方案,大致有以下几种思路

方案1:直接打印页面

js打印页面

// 快捷键 ctrl + p

window.print()

vue代码

打印预览

发现,直接打印是不行的

当使用ctrl+p 拉起打印的时候,发现总有一些小问题,比如

表格后面的竖线缺失表格的表头错位表格的列显示不全

方案2:使用css媒体查询控制打印内容

该方案适用于页面简单,打印效果过要求不高的场景

我们可以通过css媒体查询,将打印按钮隐藏

使用css媒体查询控制打印区域

@media print {

/* 隐藏不需要打印的部分 */

.not-print{

display: none !important;

}

.print{

background-color: transparent;

}

}

html中设置不打印的内容

不打印此内容

vue 完整代码

打印预览

方案3:第三方插件print-js

适用于简单输出

文档

https://github.com/crabbly/print.jshttps://printjs.crabbly.com/https://www.npmjs.com/package/print-js

安装

npm install print-js --save

使用示例

printJS({

header: "表格标题",

type: "json",

properties: [

{ field: "date", displayName: "日期" },

{ field: "name", displayName: "姓名" },

{ field: "address", displayName: "地址" },

],

printable: this.tableData,

});

vue 完整代码

打印预览

方案4:将要打印的节点内容写入iframe

可以直接将要打印的节点内容设置给iframe标签,此方法可能会出现样式不一致的问题

关键代码 utils.js

export function printHTML(html) {

// 创建iframe元素

const iframe = document.createElement('iframe')

iframe.setAttribute('style', 'display:none')

document.body.appendChild(iframe)

let doc = iframe.contentWindow.document

// 写入html

doc.write(html)

doc.close()

// 调用打印

iframe.contentWindow.focus()

iframe.contentWindow.print()

// 打印完毕后移除

iframe.parentNode.removeChild(iframe)

}

vue 完整代码

打印结果

方案5:将要打印的html写入iframe(推荐)

适用于复杂输出,需要自定义,复杂度也是最高的

我们应该换个思路:

打印的页面往往都是黑白显示,不一定要和原页面一样,很多元素可能不一样,可能还会增加额外的一些信息,索引应该单独构建html页面

我们可以使用后端模板渲染的思路,通过twig 模板引擎来渲染一个html文件,通过容器隔离的iframe来进行独立完成渲染和打印工作

安装用到的依赖

pnpm i twig twig-loader -D

模板代码

模板 print-template.twig

http-equiv="X-UA-Compatible"

content="IE=edge"

/>

name="viewport"

content="width=device-width, initial-scale=1.0"

/>

Document

{{ title }}

{% for row in list %}

{% endfor %}

日期 姓名 地址
{{ row.date }} {{ row.name }} {{ row.address }}

打印预览 至此,完整的打印了表格内容,还附带了一些必要的信息

需要配置 vue.config.js

// vue.config.js

module.exports = {

configureWebpack: {

resolve: {

fallback: {

path: require.resolve('path-browserify'),

},

},

},

chainWebpack: (config) => {

// twig rule loader

const twigRule = config.module.rule('twig')

twigRule.exclude.add(/node_modules/)

// 添加新的loader处理

twigRule

.test(/\.twig$/)

.use('twig-loader')

.loader('twig-loader')

.end()

},

}

依赖 package.json

{

"name": "vue-demo",

"version": "0.1.0",

"private": true,

"scripts": {

"serve": "vue-cli-service serve",

"build": "vue-cli-service build"

},

"dependencies": {

"dayjs": "^1.11.5",

"element-ui": "^2.15.10",

"path-browserify": "^1.0.1",

"vue": "^2.6.14"

},

"devDependencies": {

"@vue/cli-service": "~5.0.0",

"less": "^4.0.0",

"less-loader": "^8.0.0",

"twig": "^1.15.4",

"twig-loader": "^0.5.5",

"vue-template-compiler": "^2.6.14"

}

}

打印属性

/* 打印文档时修改某些 CSS 属性 */

@page {

/* 设置纸张及其方向 portrait:纵向; landscape: 横向 */

size: A4 landscape;

}

完整代码:https://github.com/mouday/vue-print/ 在线体验:https://mouday.github.io/vue-print/

参考

前端实现在浏览器中打印网页利用 iframe 标签打印元素https://developer.mozilla.org/zh-CN/docs/Web/API/Window/printhttps://developer.mozilla.org/zh-CN/docs/Web/CSS/@page

🎯 相关推荐

🎁 合作伙伴