单页显示,多页打印问题

时间:2022-07-01 08:10:28

A web page displays the following:-

网页显示如下:-

  • Bob
  • 鲍勃
  • Fred
  • 弗雷德
  • John
  • 约翰

However when the user (that would be me) prints the web page I want multiple repeats of this output with slight variations to be printed on separate pages :-

但是,当用户(也就是我)打印web页面时,我希望这个输出的多次重复,并在不同的页面上进行轻微的修改:-

  • Bob
  • 鲍勃
  • Fred
  • 弗雷德
  • John
  • 约翰

>page break here<

>这里分页符<

  • Bob
  • 鲍勃
  • Fred
  • 弗雷德
  • John
  • 约翰

>page break here<

>这里分页符<

  • Bob
  • 鲍勃
  • Fred
  • 弗雷德
  • John
  • 约翰

In reality the page content is larger (although well within a standard A4 page worth) and the number of output pages is about 20. I'd prefer an elegant cross-browser solution but ultimately a solution that works on Internet Explorer 7 is acceptable.

实际上,页面内容更大(尽管在标准的A4页面内),输出页面的数量大约为20个。我更喜欢优雅的跨浏览器解决方案,但最终可以接受在Internet Explorer 7上工作的解决方案。

I'm using ASP.NET MVC with jQuery (although a straight JavaScript solution is fine).

我用ASP。使用jQuery的NET MVC(虽然简单的JavaScript解决方案是可以的)。

Edit: Page-Break-XXX css style is going be part of the answer, but I'm particularly interested in a means to dynamically create the print version HTML from the screen version. Note I don't want to navigate to a 'printer friendly' page and then print that. I just want to hit the browsers print button and magic happens.

编辑:Page-Break-XXX css样式将是答案的一部分,但是我对从屏幕版本动态创建打印版本HTML的方法特别感兴趣。注意,我不想导航到“打印机友好”页面,然后打印出来。我只是想按下浏览器的打印按钮,神奇的事情就发生了。

3 个解决方案

#1


10  

Ok, so taking into account the comments etc to my post something like this:

好的,考虑到我的评论等等我的帖子是这样的:

For ease of display here, I'm using on page styles, but you can easily use off page references.

为了便于在这里显示,我使用的是页面样式,但是可以很容易地使用页外引用。

Declaring the following styles:

声明以下样式:

<!-- 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>

Then, you're going to need to do some heavy lifting in your view to get HTML looking something like this:

然后,你需要在视图中做一些繁重的工作来获得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>

Now for an "appropriate display method".

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

I'm just getting started with MVC, so you've probably got a better method of doing this, but for now I'd probably use a RenderPartial method like this:

我刚开始讲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});
  }
%>

Your user control can then handle the bulk of the display, setting the class of the containing divs (or whatever element you use) as appropriate, and bolding up the user based on the one passed in - as I said, there's possibly a better way of doing the partial stuff.

然后,您的用户控件可以处理显示的大部分内容,适当地设置包含div(或您使用的任何元素)的类,并根据传入的内容对用户进行粗加—正如我所说,可能有更好的方法来完成部分内容。

Obviously, you probably want completely different rendering of the users for display and print - I guess you're probably adding quite a bit of jQuery goodness hiding and displaying stuff, etc, that you are actually going to display on the printed version, so you probably want two differnt user controls, and can then get away with not passing in the IsPrintable property.

显然,你可能想要呈现完全不同的用户显示和打印,我猜你可能增加相当多的jQuery善良隐藏和显示的东西,等等,你会显示在打印版本,所以你可能想要两个不同的用户控件,可以侥幸没有传入IsPrintable属性。

Also, as it stands, this will print a blank page at the end, due to the "page-break-after" style on all divs - you'd possibly want to note that you're on the last div, and have a different style on that, unless you have information that you'd like on that last page.

另外,目前,这将打印空白页最后,由于“page-break-after”风格在所有div——你可能要注意,你在过去的div,和有不同的风格,除非你有你想在最后一页的信息。

#2


2  

I'm not sure you can do it all via CSS, but here's some to get you started.

我不确定你是否可以通过CSS来实现这一切,但是这里有一些可以帮助你开始。

To get a page break in CSS when printing use one of:

当打印使用时,要在CSS中获得分页符:

These take values of:

这些花的值:

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

If you're prepared to have some sort of "Print" page that lists the information as you want, with those styles on the repeated elements, you should be good to go.

如果您准备有某种“打印”页,列出您想要的信息,在重复的元素上有这些样式,那么您应该走了。

#3


1  

You will need to do it all via JavaScript, create a print link that when clicked calls window.print().

您将需要通过JavaScript完成这一切,创建一个在单击时调用windows .print()的打印链接。

However before that is called create the output that you want and place it into a seperate container (div, span, any html element that supports the tags you are going to place within it). Hide the container using your main stylesheet and create a seperate stylesheet for print media. Within that new stylesheet show the container element and hide the old elements and anything else that you do not wish to print.

然而,在此之前,调用创建您想要的输出并将其放置到一个隔离容器中(div, span,任何支持您将在其中放置标记的html元素)。使用主样式表隐藏容器,并为打印媒体创建一个分离样式表。在这个新样式表中显示了容器元素并隐藏了旧元素和其他您不希望打印的元素。

If you want to clean up the page afterwards then set an interval using SetInterval to clear up the unwanted container. I wouldn't do it immediately after calling window.print() because I imagine the printer would not pick up on the HTML changes, however a quick test will tell you otherwise.

如果您想在之后清理页面,那么使用SetInterval设置一个间隔来清除不需要的容器。在调用windows .print()之后,我不会立即执行此操作,因为我认为打印机不会接收HTML更改,但是快速测试会告诉您相反的情况。

If there is a way of listening for a print of your page using javascript then you could hook up that as well.

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

Edit: As you are using jQuery I would clone the original list by using

编辑:当您使用jQuery时,我将使用jQuery克隆原始列表

$('#listID').clone().appendTo('#hiddencontainer')

Clone documentation

复制文档

#1


10  

Ok, so taking into account the comments etc to my post something like this:

好的,考虑到我的评论等等我的帖子是这样的:

For ease of display here, I'm using on page styles, but you can easily use off page references.

为了便于在这里显示,我使用的是页面样式,但是可以很容易地使用页外引用。

Declaring the following styles:

声明以下样式:

<!-- 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>

Then, you're going to need to do some heavy lifting in your view to get HTML looking something like this:

然后,你需要在视图中做一些繁重的工作来获得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>

Now for an "appropriate display method".

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

I'm just getting started with MVC, so you've probably got a better method of doing this, but for now I'd probably use a RenderPartial method like this:

我刚开始讲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});
  }
%>

Your user control can then handle the bulk of the display, setting the class of the containing divs (or whatever element you use) as appropriate, and bolding up the user based on the one passed in - as I said, there's possibly a better way of doing the partial stuff.

然后,您的用户控件可以处理显示的大部分内容,适当地设置包含div(或您使用的任何元素)的类,并根据传入的内容对用户进行粗加—正如我所说,可能有更好的方法来完成部分内容。

Obviously, you probably want completely different rendering of the users for display and print - I guess you're probably adding quite a bit of jQuery goodness hiding and displaying stuff, etc, that you are actually going to display on the printed version, so you probably want two differnt user controls, and can then get away with not passing in the IsPrintable property.

显然,你可能想要呈现完全不同的用户显示和打印,我猜你可能增加相当多的jQuery善良隐藏和显示的东西,等等,你会显示在打印版本,所以你可能想要两个不同的用户控件,可以侥幸没有传入IsPrintable属性。

Also, as it stands, this will print a blank page at the end, due to the "page-break-after" style on all divs - you'd possibly want to note that you're on the last div, and have a different style on that, unless you have information that you'd like on that last page.

另外,目前,这将打印空白页最后,由于“page-break-after”风格在所有div——你可能要注意,你在过去的div,和有不同的风格,除非你有你想在最后一页的信息。

#2


2  

I'm not sure you can do it all via CSS, but here's some to get you started.

我不确定你是否可以通过CSS来实现这一切,但是这里有一些可以帮助你开始。

To get a page break in CSS when printing use one of:

当打印使用时,要在CSS中获得分页符:

These take values of:

这些花的值:

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

If you're prepared to have some sort of "Print" page that lists the information as you want, with those styles on the repeated elements, you should be good to go.

如果您准备有某种“打印”页,列出您想要的信息,在重复的元素上有这些样式,那么您应该走了。

#3


1  

You will need to do it all via JavaScript, create a print link that when clicked calls window.print().

您将需要通过JavaScript完成这一切,创建一个在单击时调用windows .print()的打印链接。

However before that is called create the output that you want and place it into a seperate container (div, span, any html element that supports the tags you are going to place within it). Hide the container using your main stylesheet and create a seperate stylesheet for print media. Within that new stylesheet show the container element and hide the old elements and anything else that you do not wish to print.

然而,在此之前,调用创建您想要的输出并将其放置到一个隔离容器中(div, span,任何支持您将在其中放置标记的html元素)。使用主样式表隐藏容器,并为打印媒体创建一个分离样式表。在这个新样式表中显示了容器元素并隐藏了旧元素和其他您不希望打印的元素。

If you want to clean up the page afterwards then set an interval using SetInterval to clear up the unwanted container. I wouldn't do it immediately after calling window.print() because I imagine the printer would not pick up on the HTML changes, however a quick test will tell you otherwise.

如果您想在之后清理页面,那么使用SetInterval设置一个间隔来清除不需要的容器。在调用windows .print()之后,我不会立即执行此操作,因为我认为打印机不会接收HTML更改,但是快速测试会告诉您相反的情况。

If there is a way of listening for a print of your page using javascript then you could hook up that as well.

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

Edit: As you are using jQuery I would clone the original list by using

编辑:当您使用jQuery时,我将使用jQuery克隆原始列表

$('#listID').clone().appendTo('#hiddencontainer')

Clone documentation

复制文档