VUE根據后端數據生成多個表格並且每一個表格能完整打印


效果(這里金額為或者字段為空不顯示)

顯示

打印,不會有表格是分兩頁打印的,根據自己需要設置一頁打印多少個表格

根據后端數據生成多個表格

html部分

<div id="bodyPrintGz">
        <div id="gzDiv"></div>
      </div>

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", "width:100px;font-size:12px;");
                  }
                  //把單元格添加進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", "width:100px;font-size:12px;");
                  }
                  tr2.appendChild(td2);
                }
                table.appendChild(tr2);
              }
              var trs = Array.from(table.getElementsByTagName("tr"));
              table.setAttribute("border", "1");
              table.setAttribute("cellspacing", "0");
              table.setAttribute("style", "margin-bottom:20px;");
              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", "page-break-after:always;");
          div1.appendChild(div2);
          div2 = document.createElement("div");
          div2.appendChild(tb);
          if (index == tables.length - 1) {
            //div2.setAttribute("style", "page-break-after:always;");
            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", nullable = false)
    private int ztId;
    @Nationalized
    @Column(length = 50, nullable = false)
    private String qj;
    @Nationalized
    @Column(name = "gzlb_id", length = 50, nullable = false)
    private String gzlbId;
    @Nationalized
    @Column(name = "bm_name", length = 50, nullable = false)
    private String bmName;
    @Nationalized
    @Column(name = "gz_num", length = 50, nullable = false)
    private String gzNum;
    @Nationalized
    @Column(length = 50, nullable = false)
    private String name;
    @Column(name = "field_id", length = 255, nullable = false)
    private String fieldId;
    @Column(name = "row_num", nullable = false)
    private int rowNum;
    @Column(columnDefinition = "CLOB", nullable = false)
    private String kzl;

(2)view類

public class GzView {
    private List<GzlrValue> headers;
    private List<GzlrValue> bodys;

    public List<GzlrValue> getHeaders() {
        return headers;
    }

    public void setHeaders(List<GzlrValue> headers) {
        this.headers = headers;
    }

    public List<GzlrValue> getBodys() {
        return bodys;
    }

    public void setBodys(List<GzlrValue> bodys) {
        this.bodys = bodys;
    }
}
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 +
                ", value='" + value + '\'' +
                '}';
    }
}

controller

@GetMapping("/gzdy")
    public  List<GzView> gzdy(@RequestParam(value = "ztId") int ztId, @RequestParam(value = "bmName") String bmName,
                              @RequestParam(value = "gzlb") int gzlb, @RequestParam(value = "qj") String qj) throws JsonProcessingException {
       
        List<GzView> items = new ArrayList<>();
        logger.info("這是期間" + qj);

        List<Gzdr> gzdrLisr = gzdrRepository.findAllByZtIdAndBmNameAndGzlbIdAndQj(ztId, bmName, String.valueOf(gzlb), qj);
        int count = gzdrLisr.size();
        logger.info("這是部門有多少個人" + count);
        //拿到唯一的表頭
        List<String> collect = gzdrLisr.stream().map(Gzdr::getFieldId).distinct().collect(Collectors.toList());
        Gzdr headerGzdr = gzdrRepository.findAllByFieldIdAndRowNum(collect.get(0), 0);
        logger.info("這是唯一的表頭" + headerGzdr);
        for (var gzdr : gzdrLisr) {
            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<GzlrValue> headers = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        List<GzlrValue> bodys = new ArrayList<>();
        GzlrValue it = new GzlrValue();
        it.setId(1);
        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<GzlrValue> cells1 = objectMapper.readValue(gzdr.getKzl(), new TypeReference<>() {
        });
        List<GzlrValue> collect = cells1.stream().filter(x -> !x.getValue().equals("0.0")).collect(Collectors.toList());
        bodys.addAll(collect);
        gzView.setBodys(bodys);
        List<Header> headers1 = objectMapper.readValue(headerGzdr.getKzl(), new TypeReference<>() {
        });
        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<Header> collect1 = headers1.stream().filter(x -> x.getId() == bd.getId()).collect(Collectors.toList());
                it.setValue(collect1.get(0).getValue());
                headers.add(it);
            }
        }
        gzView.setHeaders(headers);
        return gzView;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM