前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >表格打印分页实践小结

表格打印分页实践小结

作者头像
RobinsonZhang
发布2018-12-28 16:14:46
1.7K0
发布2018-12-28 16:14:46
举报

前言

print作为浏览已经比较成熟的技术可以经常被用来打印页面的部分内容,我们可以在mdn上查看到mdn相关的简单介绍。

备注:juqery的print除了基本的打印之外,还可以控制一些基本的样式,标题,页眉页脚的设置等。

需求

本文主要介绍的不是以上的基本点,而是table在打印的时候,会因为一页无法承载而导致分页,然而我们并不知道分页之后的效果,当我们点击预览的时候才发现,原来一个整体的表格被分为了两个部分,而且还是同一行的被分割坏了。

那么产品无疑是希望体验升级的: – 在页面查看时直接显示打印之后的效果,对于打印预览是有心里预期的,可以直接展示出什么位置会分页。所以我在代码设计上,直接为每个分页的部分直接变为新分割一个表格,然后通过页面的margin间距,在展示时就有分页的预期效果。

代码语言:javascript
复制
.m-print-table{
    &:not(:first-child){
        margin-top:10px
    }

}
  • 将print对于表格的分页进行代码设计,通过代码计算出当前页的空间是否还能放下当前行,如果可以那么显示并循环;如果不可以,计算本行内容的大小,进行计算分割出还可以放下几行内容,剩下的内容放到下一页。

常识

展示高度

页面的展示高度一般设置为950

ui页面 && 打印预览

ui页面的显示与打印预览的部分有较大的差别,并不是完全打印ui页面的效果。

  • 一般情况下,每行所承载的数据量和ui页面是不同的。
  • 一般情况下打印很多情况下需要分页,而ui上其实数据多页面也是连在一起的。

代码的设计原则

原本的页面模板

准备好进行按照预览规则拆分首先需要一个原来的表格模板,以及以后打印之后的容器模板。

为了简化模型,我这里只考虑两列,左边为数据项,右边为内容的表格。

代码语言:javascript
复制
// 要处理的原表格模板的所有tr
let trs = $('#demoTable').find('tr')
// 打印之后显示的table存放的容器
// 内容进行转换
let $container = $('#printContainer')

准备好分页的间隔模板

代码语言:javascript
复制
const tableHeader = '<table class="m-print-table-process"><tbody>'
const tableFooter = '</tbody></table><div class="pager"></div>'

分页符的样式

因为我的ui体验是设计页面展示时也进行相应的分页,所以没有加媒体查询,你可以去根据自己的需要决定是否需要加。

代码语言:javascript
复制
.pager{
    page-break-after:always;
}
@media print{
    //媒体查询样式
}

判断条件

代码语言:javascript
复制
// 是否是初始页 初始页可能会有一些抬头信息,比如下卖弄的81高度
let pageInit = true
// 默认的页面高度
let pageHeight = 950
// 初始化页面高度参数为0 不断累加
let initHeight = 0
// 计算当前页面的可用展示高度,每次进入新页面重新计算
let currentPageHeight = pageInit ? pageHeight - 81 : pageHeight;
// 获取当前行的高度
let height = idStr && (idStr === 'processList' || idStr === 'billList') ? this.getHeight(strArr) : 35

// 如果高度大于当前可展示高度 
if(initHeight >= currentPageHeight || (initHeight + height >= currentPageHeight){


}

区分的根据不同类型进行展示

  • 展示数据为数组的
代码语言:javascript
复制
// 特殊业务类型的
// 目前只考虑两页之内可以放下
// 获取分割后的数组 以及新的页面高度(传入当前行字符串,当前页面剩余可展示高度)
let {countArr, newPageHeight} = this.getSplitArr(strArr, currentPageHeight - initHeight)
countArr.map((item, index) => {
// 当前的继续追加到表格中 下一个重开表格
if (index === 0) {
    let tdStr = item.map(it => `${it}<br/>`).join('')
    tempHtml += `<tr><td>${typeStr}</td><td>${tdStr}</td></tr>`
} else if (index === 1) {
    if (item.length > 0) {
        tempHtml = tempHtml + tableFooter + tableHeader
        let tdStr = item.map(it => `${it}<br/>`).join('')
        tempHtml += `<tr><td>${typeStr}</td><td>${tdStr}</td></tr>`
    } 
    initHeight = newPageHeight
}
})
  • 展示数据为基本数据字符串类型的
代码语言:javascript
复制
tempHtml = tempHtml + tableFooter + tableHeader
tempHtml += `<tr>${trs[i].innerHTML}</tr>`
initHeight = initHeight - currentPageHeight + height
pageInit = false
  • 当前页还可以放下数据的,正常拼接
代码语言:javascript
复制
tempHtml += `<tr>${trs[i].innerHTML}</tr>`
initHeight += height

分割字符串数组的方法

其中计算高度的部分,40为经过试验后每行剩余可展示的科学可用的40个中文字符,而25位默认一行数据所需要的高度。

备注:这里我业务展示的数据是一个数组结构,如果你的是字符串结构要比我的判断简单很多。

经过这个方法将数据进行分割到两个数据后(countArr),前面的部分放到上一页,剩下的数据放到下一页,并计算出下一页还剩余的空间(newPageHeight),暂时没考虑第二页也放不下的情况。

代码语言:javascript
复制
   /**
     * @description 根据数组以及页面剩余高度,拆分数据数组
     * @param {Array} dataArr
     * @param {Number} remainHeight
     */
     getSplitArr(dataArr, remainHeight) {
         if (!dataArr || dataArr.length === 0) console.warn('数据为空')
         let getHeight = (data) => Math.ceil(data.length / 40) * 25
         let countArr = [[], []]
         let partIndex = 0 
         let totalHeight = remainHeight + 20
         let newPageHeight = dataArr.reduce((countHeight, item) => {
            countHeight += getHeight(item)
            if (countHeight < totalHeight) {
                countArr[partIndex].push(item)
            } else {
                totalHeight = 930
                countHeight = 0
                partIndex++
                countArr[partIndex].push(item)
            }
            return countHeight
         }, 0)
         return {countArr, newPageHeight}
     },

计算高度的方法

备注:仅供参考建议。+20为保留的每个tr行的上下padding.

代码语言:javascript
复制
getHeight(dataArr) {
    let getHeight = (data) => Math.ceil(data.length / 40) * 25
    return dataArr.reduce((countHeight, item) => {
            countHeight += getHeight(item)
            // console.log(countHeight)
            return countHeight 
        }, 0) + 20
    }

小结

以上是这次表格分页小小的实践,虽然浏览器打印整页已经技术非常成熟,但是根据产品需求进行指定的分页和一些数据的分割控制和显示还是需要一些代码设计的。

希望能帮助到你实现这部分需求的实现。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 需求
  • 常识
    • 展示高度
      • ui页面 && 打印预览
      • 代码的设计原则
        • 原本的页面模板
          • 准备好分页的间隔模板
            • 分页符的样式
              • 判断条件
                • 区分的根据不同类型进行展示
                  • 分割字符串数组的方法
                    • 计算高度的方法
                    • 小结
                    相关产品与服务
                    容器服务
                    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档