7

有没有办法动态检查 PDFMake 中的剩余页面高度?动态创建页面时,我希望能够检查剩余的可用页面高度以将其与元素高度进行比较,以便页面上的最后一个元素(例如图像或长文本区域内容)不能被​​剪切而是转移到另一个页面反而。不知道如何动态地做到这一点。

4

4 回答 4

6

感谢大家。我最终使用了 pageBreakBefore 函数和作为标记的 headerLevel,并找到了一个 pdfmake 版本,它允许我们查看节点是否为图像,从而计算元素的高度。这是它在我的代码中的外观。那里我还有一个页脚,必须在我的计算中考虑它,以便内容不应该继续存在:

pageBreakBefore: function(currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage) {
          var pageInnerHeight = currentNode.startPosition.pageInnerHeight;
          var top = (currentNode.startPosition.top) ? currentNode.startPosition.top : 0;
          var footerHeight = 30;
          var nodeHeight = 0;
          if (followingNodesOnPage && followingNodesOnPage.length) {
            nodeHeight = followingNodesOnPage[0].startPosition.top - top;
          }

          if (currentNode.headlineLevel === 'footer') return false;

          return (currentNode.image && (top + nodeHeight + footerHeight > pageInnerHeight))
              || (currentNode.headlineLevel === 'longField' && (top + nodeHeight + footerHeight > pageInnerHeight))
              || currentNode.startPosition.verticalRatio >= 0.95;
        }
于 2017-01-04T10:21:17.893 回答
5

好吧,我可能有点晚了。但是在 0.1.17 版本中,他们引入了pageBreakBefore函数。

Github 上的发行说明

您现在可以指定 pageBreakBefore 函数,该函数可以确定是否应在分页符之前插入分页符。要实施“无孤儿”规则,可能如下所示:

var dd = {
  content: [
    {text: '1 Headline', headlineLevel: 1},
    'Some long text of variable length ...',
    {text: '2 Headline', headlineLevel: 1},
    'Some long text of variable length ...',
    {text: '3 Headline', headlineLevel: 1},
    'Some long text of variable length ...',
  ],
  pageBreakBefore: function(currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage) {
    return currentNode.headlineLevel === 1 && followingNodesOnPage.length === 0;
  }
}

如果 pageBreakBefore 返回 true,则会在 currentNode 之前添加分页符。当前节点附有以下信息:

{
 id: '<as specified in doc definition>', 
 headlineLevel: '<as specified in doc definition>',
 text: '<as specified in doc definition>', 
 ul: '<as specified in doc definition>', 
 ol: '<as specified in doc definition>', 
 table: '<as specified in doc definition>', 
 image: '<as specified in doc definition>', 
 qr: '<as specified in doc definition>', 
 canvas: '<as specified in doc definition>', 
 columns: '<as specified in doc definition>', 
 style: '<as specified in doc definition>', 
 pageOrientation '<as specified in doc definition>',
 pageNumbers: [2, 3], // The pages this element is visible on (e.g. multi-line text could be on more than one page)
 pages: 6, // the total number of pages of this document
 stack: false, // if this is an element which encapsulates multiple sub-objects
 startPosition: {
   pageNumber: 2, // the page this node starts on
   pageOrientation: 'landscape', // the orientation of this page
   left: 60, // the left position
   right: 60, // the right position
   verticalRatio: 0.2, // the ratio of space used vertically in this document (excluding margins)
   horizontalRatio: 0.0  // the ratio of space used horizontally in this document (excluding margins)
 }
}
于 2016-11-14T10:22:33.167 回答
0

我最近在开发大会上与一位同事交谈。他们面临同样的问题。如果您真的需要知道,据我所知有两种可能性:

1)测试渲染页面数据并检查输出是否超过一页。这是 derpy,但你不知道内部结构。

2) 在生成 pdf 之前,自己进行在 pdfmake 中完成的计算。不幸的是,关于如何您需要查看 pdfmake 生成代码本身。

如果有更优雅的解决方案,我非常想了解自己!

于 2016-07-05T08:18:42.703 回答
0

我是手动做的。在文本开始出现之前,您只需要知道页面的最大大小是多少。就我而言,Legal 纸张大小在文本被截断之前的最大宽度为 700 像素。

所以我要做的是减少循环中的列宽,直到 totalPageWidth 小于可接受的宽度。它可能不是很可读,但这里是代码。

// For a legal size page, total width is 700. So try and push all columns within 700
        // Following lines are there to reduce the width of columns so as to adjust the total width.
        // Width is deducted for every column so as not to affect any individual column.
        totalOutOfPageWidth = totalWidth - 700;
        var totalWidthDeducted = 0;
        while (totalOutOfPageWidth > 0) {
            for (var c = 0; c < colWidthArray.length; c++) {
                if (totalOutOfPageWidth > 0) {
                    if (colWidthArray[c] == width70 - totalWidthDeducted) {
                        colWidthArray[c] = colWidthArray[c] - 5;
                        totalOutOfPageWidth -= 5;
                    }
                }
            }
            if (totalOutOfPageWidth > 0) {
                for (var c = 0; c < colWidthArray.length; c++) {
                    if (colWidthArray[c] == width50 - totalWidthDeducted) {
                        colWidthArray[c] = colWidthArray[c] - 5;
                        totalOutOfPageWidth -= 5;
                    }
                }
            }
            if (totalOutOfPageWidth > 0) {
                for (var c = 0; c < colWidthArray.length; c++) {
                    if (colWidthArray[c] == width35 - totalWidthDeducted) {
                        colWidthArray[c] = colWidthArray[c] - 5;
                        totalOutOfPageWidth -= 5;
                    }
                }
            }
            if (totalOutOfPageWidth > 0) {
                for (var c = 0; c < colWidthArray.length; c++) {
                    if (colWidthArray[c] == width25 - totalWidthDeducted) {
                        colWidthArray[c] = colWidthArray[c] - 5;
                        totalOutOfPageWidth -= 5;
                    }
                }
            }
            totalWidthDeducted += 5;
于 2016-07-20T04:12:32.413 回答