打印HTML页面,表格元素被截断的解决方案

abstract:

获取页面中所有的table元素,计算table元素前的所有dom元素的高度,如果超出了当前可视容器的高度,那么就进行分割操作。

reference:

Window:load 事件 - Web API 接口参考 | MDN

HTML DOM Element nextSibling 属性

Q:

我的问题是:我要做一个打印HTML页面功能,这个页面的表格是动态生成的,具有多个表格,现在面临的问题是,在第一页末尾无法放下这一整个表格,如何做到将这个表格分割为两部分,第一部分占满第一页剩余的空间,第二部分放在第二页去。

这个表格是动态生成的,我无法确定从第几行分割?

A:

如果表格是动态生成的,并且你无法确定从第几行进行分割,那么就需要在生成表格时根据页面的可视高度来进行分割。

你可以使用JavaScript来获取页面的可视高度,并在生成表格时判断每个表格所占高度。当表格的高度超过页面可视高度时,就将剩余部分放在下一页打印。

<!DOCTYPE html>
<html>
<head>
  <style>
    @media print {
      table {
        display: block;
        page-break-inside: avoid;
        width: 100%;
      }
      
      .break {
        page-break-before: always;
      }
    }
  </style>
</head>
<body>
  <script>
    window.addEventListener('load', function() {
      // 获取页面可视高度
      var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

      // 获取所有表格
      var tables = document.querySelectorAll('table');

      // 循环遍历每个表格
      for (var i = 0; i < tables.length; i++) {
        var table = tables[i];
        
        // 获取表格高度
        var tableHeight = table.offsetHeight;
        
        // 如果表格高度超过页面可视高度
        if (tableHeight > pageHeight) {
          // 创建一个新的分页元素
          var breakElement = document.createElement('div');
          breakElement.classList.add('break');
          
          // 将剩余部分的表格插入到新分页元素中
          while (table.nextSibling) {
            breakElement.appendChild(table.nextSibling);
          }
          
          // 在当前表格之后插入新分页元素
          table.parentNode.insertBefore(breakElement, table.nextSibling);
          
          // 跳出循环,结束分割表格
          break;
        }
      }
    });
  </script>

  <!-- 动态生成的表格 -->
  <table>
    <!-- 表格内容 -->
  </table>

</body>
</html>

Q:

你的方法是有效的,但是需要做出一些调整,

var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

你直接获取了整个可视高度,但是这个表格之前的元素你忘记考虑了. 并且 “计算表格之前元素的高度” 不是指表格上半部分的高度,而是指表格之前其他dom元素高度

A:

你是希望计算表格之前其他 DOM 元素的高度,而不仅仅是表格上半部分的高度。

以下是经过修改的代码,以考虑表格之前其他 DOM 元素的高度:

<!DOCTYPE html>
<html>
<head>
  <style>
    @media print {
      table {
        display: block;
        page-break-inside: avoid;
        width: 100%;
      }
      
      .break {
        page-break-before: always;
      }
    }
  </style>
</head>
<body>
  <script>
    window.addEventListener('load', function() {
      // 计算可视高度
      var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

      // 获取所有表格
      var tables = document.querySelectorAll('table');

      // 循环遍历每个表格
      for (var i = 0; i < tables.length; i++) {
        var table = tables[i];

        // 计算表格之前元素的总高度
        var heightBeforeTable = 0;
        var prevElement = table.previousSibling;
        while (prevElement) {
          if (prevElement.offsetHeight) {
            heightBeforeTable += prevElement.offsetHeight;
          }
          prevElement = prevElement.previousSibling;
        }

        // 计算表格高度
        var tableHeight = table.offsetHeight;

        // 如果表格高度加上之前元素高度超过页面可视高度
        if ((tableHeight + heightBeforeTable) > pageHeight) {
          // 创建新的分页元素
          var breakElement = document.createElement('div');
          breakElement.classList.add('break');

          // 将表格插入到新分页元素中
          breakElement.appendChild(table);

          // 在当前表格之前插入新分页元素
          table.parentNode.insertBefore(breakElement, table);

          // 跳出循环,结束表格分割
          break;
        }
      }
    });
  </script>

  <!-- 动态生成的表格 -->
  <table>
    <!-- 表格内容 -->
  </table>

</body>
</html>

现在,代码会将表格之前其他 DOM 元素的高度累加,并与表格高度一起比较来决定是否需要对表格进行分割。

Q:

你的答案是正确的,我现在有一个附加的需求,让所有的表格都自适应宽度。我的要求是,对于所有的table元素,我希望宽度自适应,并且里面的每个单元格都是平均分配宽度的

A:

  <style>
    table {
      width: 100%;
      border-collapse: collapse;
    }
    
    th, td {
      padding: 8px;
      text-align: left;
      border: 1px solid #dddddd;
    }
    
    /* 让单元格自动分配宽度 */
    td {
      width: calc(100% / var(--columns));
    }
  </style>

Q:在页面上确实是平均分配了宽度,但是为什么打印时候没有这个效果?

A:在 CSS 中,通过 @media print 媒体查询可以设置打印样式,以及将其与屏幕样式分开。您可以在 @media print 媒体查询中重新设置表格的宽度和单元格的宽度,以确保在打印时也能保持相同的效果。

<style>
  @media print {
    table {
      display: table; /* 将 display 属性修改为 table */
      page-break-inside: avoid;
      width: 100%;
    }

    .break {
      page-break-before: always;
    }
  }

  table {
    width: 100%;
  }

  th,
  td {
    padding: 8px;
    text-align: align;
    border: 1px solid #754f4f;
  }

  /* 让单元格自动分配宽度 */
  td {
    width: calc(100% / var(--columns));
  }
</style>

通过将 display 属性从 block 修改为 table,您应该能够在打印时保持表格的自适应宽度效果。

猜你喜欢

转载自blog.csdn.net/dongnihao/article/details/134832992
今日推荐