单页显示,多页打印问题

时间:2009-01-16 09:08:14

标签: javascript jquery html css asp.net-mvc

网页显示以下内容: -

  • 鲍勃
  • 佛瑞德
  • 约翰

然而,当用户(可能是我)打印网页时,我希望多次重复此输出,并在不同的页面上打印: -

  • 鲍勃
  • 佛瑞德
  • 约翰

>page break here<

  • 鲍勃
  • 佛瑞德
  • 约翰

>page break here<

  • 鲍勃
  • 佛瑞德
  • 约翰

实际上页面内容较大(虽然在标准A4页面内很好),输出页面数量约为20.我更喜欢优雅的跨浏览器解决方案,但最终解决方案适用于Internet Explorer 7是可以接受的。

我正在使用带有jQuery的ASP.NET MVC(尽管直接的JavaScript解决方案很好)。

编辑: Page-Break-XXX css样式将成为答案的一部分,但我特别感兴趣的是从屏幕版本动态创建打印版本HTML的方法。注意我不想导航到“打印机友好”页面然后打印它。我只想点击浏览器打印按钮并发生魔术。

3 个答案:

答案 0 :(得分:10)

好的,所以考虑到我的帖子中的评论等等:

为了便于在此处显示,我正在使用页面样式,但您可以轻松使用离页引用。

声明以下样式:

<!-- media="print" means these styles will only be used by printing 
  devices -->
<style type="text/css" media="print">
    .printable{ 
      page-break-after: always;
    }
    .no_print{
      display: none;
    }
</style>
<!-- media="screen" means these styles will only be used by screen 
  devices (e.g. monitors) -->
<style type="text/css" media="screen">
    .printable{
      display: none;
    }
</style>
<!-- media types can be combined with commas to affect multiple devices -->
<style type="text/css" media="screen,print">
    h1{
      font-family: Arial, Helvetica, sans-serif;
      font-size: large;
      font-weight: bold;
    }
</style>

然后,您需要在视图中做一些繁重的工作,以使HTML看起来像 这样:

<!-- Intial display for screen -->
<div class="no_print">
    <!-- Loop through users here using preferred looping/display method -->
    <ul>
        <li>Bob</li>
        <li>Fred</li>
        <li>John</li>
    </ul>
</div>
<!-- Now loop through each user, highlighting as you go, but for printer* -->
<div class="printable">
    <ul>
        <li><b>Bob</b></li>
        <li>Fred</li>
        <li>John</li>
    </ul>
</div>
<div class="printable">
    <ul>
        <li>Bob</li>
        <li><b>Fred</b></li>
        <li>John</li>
    </ul>
</div>
<div class="printable">
    <ul>
        <li>Bob</li>
        <li>Fred</li>
        <li><b>John</b></li>
    </ul>
</div>

现在有了“适当的显示方法”。

我刚刚开始使用MVC,所以你可能有更好的方法来做到这一点,但是现在我可能会使用像这样的RenderPartial方法:

<%
  /* 
  Using RenderPartial to render a usercontrol,
  we're passing in the Model here as the Model for the control, 
  depends on where you've stored your objects really, then we
  create a new anonymous type containing the properties we want
  to set.
  */

  // Display the main list
  Html.RenderPartial("~/Views/Shared/Controls/UserList.ascx",
      ViewData.Model, 
      new {HighlightUser = null, IsPrintable = false});

  // Loop through highlighting each user
  foreach (var user in ViewData.Model)
  {
    Html.RenderPartial("~/Views/Shared/Controls/UserList.ascx",
      ViewData.Model, 
      new {HighlightUser = user, IsPrintable = true});
  }
%>

然后,您的用户控件可以处理大部分显示,根据需要设置包含div的类(或您使用的任何元素),并根据传入的用户加粗用户 - 正如我所说,可能做部分事情的更好方法。

显然,您可能希望用户进行完全不同的显示和打印呈现 - 我猜您可能会添加相当多的jQuery善良隐藏和显示内容等,您实际上将在打印版本上显示,所以你可能想要两个不同的用户控件,然后可以不传入IsPrintable属性。

另外,就目前情况而言,由于所有div上的“分页后”风格,这将在末尾打印一个空白页 - 你可能想要注意到你在最后一个div上,并且有不同的风格,除非你在最后一页上有你想要的信息。

答案 1 :(得分:2)

我不确定你是否可以通过CSS完成所有工作,但这里有一些可以帮助你入门。

要在打印时使用以下其中一个来获取CSS中的分页符:

这些取值为:

auto   // Default. Insert a page break before/after the element if necessary
always // Insert a page break before/after the element
avoid  // Avoid inserting a page break before/after the element
left   // Insert page breaks before/after the element until it reaches a blank left page
right  // Insert page breaks before/after the element until it reaches a blank right page

如果你准备有某种“打印”页面列出你想要的信息,那些重复元素的样式,你应该很高兴。

答案 2 :(得分:1)

您需要通过JavaScript完成所有操作,创建一个打印链接,点击后调用window.print()。

然而,在调用之前,请创建所需的输出并将其放入单独的容器(div,span,支持您将放置在其中的标记的任何html元素)。使用主样式表隐藏容器,并为打印介质创建单独的样式表。在新的样式表中显示容器元素并隐藏旧元素和您不希望打印的任何其他内容。

如果要在之后清理页面,请使用SetInterval设置间隔以清除不需要的容器。在调用window.print()之后我不会立即这样做,因为我想打印机不会接受HTML更改,但是快速测试会告诉你。

如果有一种方法可以使用javascript监听您的网页打印,那么您也可以将其连接起来。

修改 在使用jQuery时,我会使用

克隆原始列表
$('#listID').clone().appendTo('#hiddencontainer')

Clone documentation