将CSS和/或jQuery用于带分页符的打印页面

时间:2011-02-02 17:58:31

标签: jquery css printing-web-page

我有一个动态生成的html页面,可以打印。

我想基于div部分创建分页符 - 任何给定的div - 如果它不完全适合页面,则在它之前插入分页符。

从理论上讲,任何地方,从一个div,最多可能是10,可能适合单个打印页面,所以我想我需要在页面加载后使用jQuery来插入。

如果这是一个桌面应用程序,我会接近这样的事情:

  1. 测量页面宽度和高度(使用某种打印机对象)。
  2. 测量每个div高度 - 并从页面总剩余高度中减去
  3. if(remaining_space - div_height> 0){//把它放在页面上} else {// insert page break first}
  4. 有没有办法使用jQuery,CSS,原始JavaScript或其他任何方式来解决这个问题?

5 个答案:

答案 0 :(得分:3)

好的,我花了一天左右的时间来搞清楚这一点,所以我想发布我的解决方案以防万一其他人需要答案。

一般来说,这就是我所做的。

  1. 正常生成输出(非打印机预期)
  2. 创建了2个样式表(一个用于打印机,一个用于屏幕)。所有页面元素的测量结果均以英寸(不是像素为单位)转换为打印输出。
  3. 使用jQuery,我做了以下事情:
  4. - >将初始页面附加到DOM的调用函数 - 类似这样的

    // assumes old_page_id is existing element in DOM, and var page_id = 1;
    $j("<div class='page' id='" + page_id + "'><div class='print_area'></div></div>")
    .insertAfter('#' + old_page_id);
    

    - &GT;测量作为页面的div的高度(在我的例子中,$('。page')。height();)

    - &GT;运行一个函数来插入div和新页面 - 就像这样

    $('div_class').each(
     function() {
      // measure height of $(this)
      // add it to running total of used space on existing page
      // if sum total exceeds remaining space, create new page, and add to that one
      // if still room left, add to this one
     }
    );
    

    请注意,打印机样式表中的每个页面div(在我的情况下,class ='page')都有:

    page-break-after:always;

    这就是我在打印机上创建我想要的新页面的方法。

    在运行上面的jQuery函数之后,我隐藏了包含我希望移动到打印页面的div元素的原始部分。注意我无法预先隐藏此部分,因为我的jQuery测量结果不会产生有效结果(在我的情况下,我将所有div放在ID为' hide_me '的div包装器中,并设置样式到高度:1px;溢出:自动; )。

    我意识到这是非常50,000英尺的视图,但希望它对你有帮助。

答案 1 :(得分:2)

您总是可以在HTML中的点处插入一个空的DIV标记,其中包含CSS属性{pageBreakBefore:'always'}或{pageBreakAfter:'always'},您在jQuery中通过检查页面边界来计算DIV的高度或其他什么。但是你需要对页面内容有相当深入的了解,并且可能将字体大小等指定为“pt”而不是“px”。

虽然在这里查看类似的查询:

  

Enforce Print Page Breaks with CSS

答案 2 :(得分:0)

不完全是你想要的,但看看这个 http://www.javascriptkit.com/dhtmltutors/pagebreak.shtml

使用额外的JS,可能是您想要尝试实现的目标。

答案 3 :(得分:0)

您可以尝试使用此插件打印页面元素。 http://www.recoding.it/wp-content/uploads/demos/jqprint-demo.htm

如果您遵循为桌面应用程序建议的相同逻辑,这可能会有所帮助。你可以将你的“页面”包装在div中,这就是你要告诉jqPrint打印的内容。分页符可以是另一个元素,也可以是div,但是有一个类让你知道它的分页符。例如:

<div id="#page1" class="page">
...
</div>
</div id="#break1" class="break"> </div>

等。

然后

$('#page1').jqprint(); 

我不知道你是否熟悉jQuery。如果你不让我们知道。

答案 4 :(得分:0)

在我看来,印刷分页的重点是不要把事情分开。通常,您最不希望分裂的是表格数据。因此,这是一种假设您已将<div>更改为表格式并将不应拆分为<tbody>分组的行集合分组的方法。

我们希望标记要查找的代码的页眉和页脚,我们不一定希望它们出现在描述的位置

这会在页面加载时调用,但可以在打印前调用它。

<script>
    $().ready(function () {
        $('table.paged').each(function (i, o) {
            BreakPages($(o));
        })
    });
    function BreakPages(jSource) {
        $('body').width("7in");
        var perInch = $('body').width() / 7.5;
        var nPageHeight = 9 * perInch;

        var jHeader = null;
        var jFooter = null;
        var jWrapper = jSource.clone().empty();
        var jPage = null;
        var iPage = 0;
        jSource.after("<div></div>");
        var jFixed = jSource.next();

        function substed(jStuff) {
            var jCopy = jStuff.clone();
            jCopy.find('span.pageNo').html(" " + iPage + " ").removeClass('pageNo');
            return jCopy;
        }

        jSource.children().each(
            function (iChunk, oChunk) {
                var jChunk = $(oChunk);
                if (jChunk.hasClass('footer')) {
                    jFooter = jChunk;
                }
                if (jChunk.hasClass('header')) {
                    jHeader = jChunk;
                    jFooter = jChunk.nextUntil('.footer').last().next();
                }
                if (!jChunk.hasClass('sample')) {
                    var nHeight = jChunk.height();
                    if (jPage)
                        nHeight += jPage.height();
                    if (jFooter)
                        nHeight += jFooter.height();
                    if (nHeight > nPageHeight) {
                        if (jFooter)
                            jPage.append(substed(jFooter));
                        jPage.after("<p style='page-break-after:always; height:0; width:0'>&nbsp</p>");
                        jPage = null;
                    }
                    if (!jPage) {
                        iPage++;
                        jPage = jWrapper.clone();
                        jFixed.append(jPage);
                        if (jHeader && jHeader !== jChunk)
                            jPage.append(substed(jHeader));
                    }
                    jPage.append(jChunk);
                }
            }
        );
        jFixed.find('span.pageCount').html(" " + iPage + " ");
        jFixed.find('span.pageNo').html(" " + iPage + " ");
        jSource.remove();
    }
</script>

我们将表格布置成这样的分页。

<body>
    <table>
        <tbody class="header">
            PAGE ONE HEADER
        </tbody>
        <tbody class="header sample">
            LATER PAGE HEADER (IF RELEVANT)
        </tbody>
        <tbody class="together">
            ROW GROUP 1
        </tbody>

        <tbody class="together">
            ROW GROUP N
        </tbody>
        <tbody class="footer">
           FOOTER
        </tbody>
    </table>
</body>

我们扫描<tbody>并在任何注定要突破页面末尾的元素之前填充页脚和标题。

我们使用css类标记页眉和页脚,并通过将它们放在需要更改的行流中的位置来跟踪更改页眉和页脚的可能性,但是使用另一个css类使它们不可见。

令人讨厌的是,一些页面分解的实现仅适用于严格的“块”元素,所以它没有在tbody上定义。因此,我已将其应用于附加到每个页表的<p>标记类。