最近项目中,前端采用react+antd+dva的组合,已经完成了后头管理类系统产品的更新迭代工作。
今天有一个新需求,需要在后台管理系统中实现点击打印完成指定页面的打印功能。
之前也没接触过,只知道浏览器带有打印功能的实现,window.print()。
问题来了,在react中是没有dom节点的,不过我们也是可以转为dom节点的。
常规js文件打印:https://blog.csdn.net/u014267869/article/details/52539341
在react中,其实同样也是可以获取到节点信息的,在你需要打印的内容部分节点添加一个ID
打印按钮点击事件 print = () => { window.document.body.innerHTML = window.document.getElementById('billDetails').innerHTML; window.print(); window.location.reload(); }
这样打印出来的内容是没有带样式的,因为一般css文件并不会写到行内去,所以在生成html的文件字符串时,里面没有样式信息,在打印时就会布局混乱。
要想打印出来的效果与网页上显示的效果一致,就需要在生成html的文件字符串时,带上样式信息。
方法1:把样式信息写在行内
在文件信息不复杂时,可以写在行内
方法2:使用react-inline-css
使用这个npm包,可以在配置后把样式自动添加到行内
网页效果图:
打印预览竖版效果图:
横版效果图:
打印效果图:
import React, { PureComponent } from 'react';
import moment from 'moment';
import { connect } from 'dva';
import {
Card,
Button,
Form,
Table,
message,
} from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import { fixedZeroTo4Bit } from '../../utils/utils';
import styles from './Funds.less';
import { isEmptyObject } from '../../utils/reg';
import { Yuan } from '../../utils/math';
import watermark from '../../assets/icon/revocation.png';
@connect(({ finance, loading }) => ({
finance,
loading: loading.models.list,
}))
@Form.create()
export default class LoanSettleMent extends PureComponent {
constructor(props) {
super(props);
this.state = {
loading: true,
};
}
componentDidMount() {
const code = !isEmptyObject(this.props.match) ? this.props.match.params.id : 0;
this.statisticalInfo({ receiptsCode: code });
}
// 结算单列表详情
statisticalInfo(params) {
this.props.dispatch({
type: 'finance/statisticalInfo',
payload: params,
}).then(() => {
this.setState({
loading: false,
})
});
}
// 撤销操作
fetchRevocation(params) {
this.props
.dispatch({
type: 'finance/fetchRevocation',
payload: params,
})
.then(() => {
const { finance: { revocationData } } = this.props;
const { code } = revocationData;
if (code === 200) {
message.info('撤销货款单成功!').then(() => {
window.location.href = '/funds/loansettlement';
});
} else {
message.info('撤销货款单失败!');
}
});
}
// 撤销
cancer = () => {
const code = !isEmptyObject(this.props.match) ? this.props.match.params.id : 0;
this.fetchRevocation({
receiptsCode: code,
});
};
// 返回
back = () => {
window.history.back();
};
// 打印
print(){
window.document.body.innerHTML = window.document.getElementById('billDetails').innerHTML;
window.print();
window.location.reload();
}
render() {
const { finance: { statisticalInfo }, loading } = this.props;
let data = [],
createName,
createTime;
if (statisticalInfo && !Array.isArray(statisticalInfo)) {
data = statisticalInfo;
createName = statisticalInfo.createName;
createTime = statisticalInfo.createTime;
}
if (statisticalInfo != undefined) {
data = statisticalInfo.goodsVos;
}
let _data = [],
receiptsCode;
if (statisticalInfo && !Array.isArray(statisticalInfo)) {
_data = statisticalInfo;
receiptsCode = statisticalInfo.receiptsCode;
}
const { supplierName, carNo, stallName, startTime, endTime, enable } = _data;
const len = data.length;
const columns = [
{
title: '品种',
dataIndex: 'attrName',
align: 'center',
},
{
title: '销售货款',
dataIndex: 'goodsAmount',
align: 'left',
render: (text, record, index) => {
const { goodsAmount, goodsPaymentStr } = record;
const type = goodsPaymentStr !== null ? goodsPaymentStr.split('负').length : -1;
if (index < len - 1) {
return {goodsAmount ? Yuan(goodsAmount, 2) : ''};
}
return {
children:
type == 2 ? (
{goodsPaymentStr}
) : (
{goodsPaymentStr}
),
props: {
colSpan: 7,
},
};
},
},
{
title: '件数',
dataIndex: 'number',
align: 'center',
render: (text, record, index) => {
const { number } = record;
if (index < len - 1) {
return {number ? number : ''};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
{
title: '重量',
dataIndex: 'weight',
align: 'center',
render: (text, record, index) => {
const { weight } = record;
if (index < len - 1) {
return {weight ? weight : ''};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
{
title: '平均售价',
dataIndex: 'averageAmount',
align: 'center',
render: (text, record, index) => {
const { averageAmount } = record;
if (index < len - 1) {
return {averageAmount ? Yuan(averageAmount, 2) : ''};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
{
title: '平均重量',
dataIndex: 'averageWeight',
align: 'center',
render: (text, record, index) => {
const { averageWeight } = record;
if (index < len - 1) {
return {averageWeight ? averageWeight : ''};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
{
title: '费用类型',
dataIndex: 'type',
align: 'center',
render: (text, record, index) => {
const { type } = record;
if (index < len - 1) {
return {type};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
{
title: '扣款金额',
dataIndex: 'amount',
align: 'center',
render: (text, record, index) => {
const { amount } = record;
if (index < len - 1) {
return {amount !== null ? Yuan(amount, 2) : ''};
}
return {
children: '',
props: {
colSpan: 0,
},
};
},
},
];
return (
{stallName}
{`NO:${receiptsCode !== undefined ? receiptsCode : ''}`}
商品销售车次结算单
{`货老板:${supplierName !== undefined ? supplierName : ''} ${
carNo !== undefined ? fixedZeroTo4Bit(carNo, 4) : 0
}车`}
{`到货时间:${moment(startTime).format('YYYY-MM-DD')}`}
{`售罄时间:${moment(endTime).format('YYYY-MM-DD')}`}
{`结算人:${createName !== undefined ? createName : ''}`}
{`结算时间:${moment(createTime).format(
'YYYY-MM-DD'
)}`}
);
}
}