效果(这⾥⾦额为或者字段为空不显⽰)显⽰
打印,不会有表格是分两页打印的,根据⾃⼰需要设置⼀页打印多少个表格
根据后端数据⽣成多个表格html部分
js部分,虽然innerHTML也可以完成显⽰,我⼀开始也是⽤innerHTML来做的,但是后⾯打印的时候,innerHTML没有内容,所以改⽤了appendChild来⽣成表格
selectGz() { if (
this.ztId != \"\" &&
this.company != \"\" && this.gzlb != \"\" &&
this.yearAndMonth != \"\" ) {
httpGet(
`/xxxxx/gzdr/gzdy/?ztId=${this.ztId}&bmName=${this.company}&gzlb=${this.gzlb}&qj=${this.yearAndMonth}` )
.then(rst => { this.items = rst;
var div = document.getElementById(\"gzDiv\"); //先把旧数据删除
while (div.hasChildNodes()) {
//当div下还存在⼦节点时 循环继续 div.removeChild(div.firstChild); }
//新数据遍历⽣成多个表格,每⾏最多16列 this.items.forEach(x => { //创建table元素
var table = document.createElement(\"table\"); for (let i = 0; i < this.ceil(x.headers.length); i++) { //创建表头tr元素
var tr1 = document.createElement(\"tr\"); for (
let j = i * 16;
j < (x.headers.length > 16 ? (i + 1) * 16 : x.headers.length); j++ ) {
//创建td元素
var td1 = document.createElement(\"td\"); if (x.headers[j]) { //创建内容
var textnode1 = document.createTextNode(x.headers[j].value); //把内容添加进单元格
td1.appendChild(textnode1); //设置单元格样式
td1.setAttribute(\"style\ }
//把单元格添加进tr元素⾥⾯ tr1.appendChild(td1); }
//把表头添加进table⾥⾯ table.appendChild(tr1); //创建数据tr元素
var tr2 = document.createElement(\"tr\"); for (
let k = i * 16;
k < (x.bodys.length > 16 ? (i + 1) * 16 : x.bodys.length); k++ ) {
var td2 = document.createElement(\"td\"); if (x.bodys[k]) {
var textnode2 = document.createTextNode(x.bodys[k].value); td2.appendChild(textnode2);
td2.setAttribute(\"style\ }
tr2.appendChild(td2); }
table.appendChild(tr2); }
var trs = Array.from(table.getElementsByTagName(\"tr\")); table.setAttribute(\"border\
table.setAttribute(\"cellspacing\
table.setAttribute(\"style\ div.appendChild(table); }); })
.catch(e => this.$message.error(e.message)); } },
ceil(data) { //向上取整
return Math.ceil(data / 16); }
打印
import printJS from \"print-js\";
onPrint() {
var par = document.getElementById(\"gzDiv\");
var tables = Array.from(par.getElementsByTagName(\"table\")); var div1 = document.createElement(\"div\"); var div2 = document.createElement(\"div\"); var ht = 0;
tables.forEach((tb, index) => {
//获取表格的⾼度,⽤⼀个变量来保存,⽽不是tb.offsetHeight直接运算,要不然最后的表格有问题,我就试过 var tbh = tb.offsetHeight; ht = ht + tbh;
//横向打印,限制⼀张A4纸,最多打印600⾼度,当超过时换页 if (ht <= 600) {
div2.appendChild(tb);
if (index == tables.length - 1) { div1.appendChild(div2); } else {
//设置每个表格之间的间距为20 ht = ht + 20; }
} else {
//当超过600时,div加上换页样式,强制换页
div2.setAttribute(\"style\ div1.appendChild(div2);
div2 = document.createElement(\"div\"); div2.appendChild(tb);
if (index == tables.length - 1) {
//div2.setAttribute(\"style\ div1.appendChild(div2); } else {
ht = tbh + 20; } } });
//上⾯已经拿了之前的child了,所以此时的par的⼦节点为空的 // var childs = Array.from(par.children); // childs.forEach(ch => { // par.removeChild(ch); // });
//直接把新的div⼦节点append到par⾥ par.appendChild(div1); //放⼤到原来的1.2倍 par.style.zoom = 1.2; printJS({
printable: \"gzDiv\ type: \"html\
targetStyles: [\"*\"] }); //还原
par.style.zoom = 1; },
前端是主要的,提供思路
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------后端的封装是根据前端想要怎么样来封装的
后端封装视图层,关键的是:表头和内容是⼀⼀对应的
(1)model类,其中有5个字段是固定的,还有⼀个字段是扩展列kzl(表头不固定,存放多个表格内容),数据库中第1⾏存的是表头,之后才是内容
@Entity(name = \"xxxxx.Gzdr\")@Table(name = \"xxxxx_gzdr\")
public class Gzdr implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO) private int id;
@Column(name = \"zt_id\false) private int ztId; @Nationalized
@Column(length = 50, nullable = false) private String qj; @Nationalized
@Column(name = \"gzlb_id\false) private String gzlbId; @Nationalized
@Column(name = \"bm_name\false) private String bmName; @Nationalized
@Column(name = \"gz_num\false) private String gzNum; @Nationalized
@Column(length = 50, nullable = false) private String name;
@Column(name = \"field_id\false) private String fieldId;
@Column(name = \"row_num\false) private int rowNum;
@Column(columnDefinition = \"CLOB\false) private String kzl;
(2)view类
public class GzView {
private List public void setHeaders(List public List public void setBodys(List public class GzlrValue { private int id; private String value; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } @Override public String toString() { return \"GzlrValue{\" + \"id=\" + id + \ '}'; }} controller @GetMapping(\"/gzdy\") public List @RequestParam(value = \"gzlb\") int gzlb, @RequestParam(value = \"qj\") String qj) throws JsonProcessingException { List List logger.info(\"这是部门有多少个⼈\" + count); //拿到唯⼀的表头 List items.add(getView(headerGzdr,gzdr)); } logger.info(\"这是最终集合\" + items.toString()); return items; } private GzView getView(Gzdr headerGzdr, Gzdr gzdr) throws JsonProcessingException { GzView gzView = new GzView(); List ObjectMapper objectMapper = new ObjectMapper(); List it.setValue(gzdr.getQj()); bodys.add(it); it = new GzlrValue(); it.setId(2); it.setValue(gzdr.getBmName()); bodys.add(it); it = new GzlrValue(); it.setId(3); it.setValue(gzdr.getGzNum()); bodys.add(it); it = new GzlrValue(); it.setId(4); it.setValue(gzdr.getName()); bodys.add(it); List List List for (var bd : bodys) { if (bd.getId() <= 4) { it = new GzlrValue(); it.setId(bd.getId()); switch (bd.getId()) { case 1: it.setValue(\"期间\"); break; case 2: it.setValue(\"部门名称\"); break; case 3: it.setValue(\"⼯资号\"); break; case 4: it.setValue(\"姓名\"); break; default: break; } headers.add(it); } else { it = new GzlrValue(); it.setId(bd.getId()); List gzView.setHeaders(headers); return gzView; } 因篇幅问题不能全部显示,请点此查看更多更全内容