【问题标题】:Print Headers on each page Print.CSS在每页上打印标题 Print.CSS
【发布时间】:2017-02-21 15:14:18
【问题描述】:

我有一个包含对象列表的视图。

例如,如果我有一个人员列表.. 按他们所在的位置和他们所在的部门排序:

|  ID  |  Name  |  Location    |  Division  |          Age   |
--------------------------------------------------------------
    1     John      Building1      Finance              25
    2     Alex      Building1      Finance              30
    3     Chris     Building2      ISS                  22
    4     Justin    Building1      Human Resources      41
    5     Mary      Building2      Accounting           43 
    6     Ian       Building1      Human Resources      27
    7     John      Building1      Finance              35

所以我的操作返回语句如下所示:

lstOfPersonnel = lstOfPersonnel.OrderBy(x => x.Location).ThenBy(x => x.Division).ThenBy(x => x.Name).ToList();

return View(lstOfPersonnel);

在我看来,我有这个:

<table class="table table-bordered no-border">
    @foreach (var item in Model)
    {
        if ((Model.IndexOf(item) == 0) || ((Model.IndexOf(item) != 0) && (!item.Building.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Building) || !item.Division.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Division))))
        {
                <thead>
                    <tr>
                        <th><b>@item.Building</b></th>
                        <th><b>@item.Division</b></th>
                    </tr>


                    <tr class="no-display"></tr>
                    <tr>
                        <th>Name</th>
                    </tr>
                    <tr>
                        <th>Age</th>
                    </tr>
                </thead>


                <tbody>
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                </tbody>
        }
        else
        {
            <tbody>
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Age)
                    </td>
                </tr>
            </tbody>
        }
    }
</table>

现在,当我打印预览时,它会将同一建筑物和分区中的每个人放在各自的标题下。但是,第一个 &lt;thead&gt; 元素.. 可以说这个例子是 Building1Finance,因为 .OrderBy.. 显示在 每个 页面的顶部下一座建筑。

所以对于视觉效果,这就是我打印预览时的样子:

第 1 页:

// Perfect Render
Building1 | Finance

Name    |    Age
Alex          30
John          35
John          25

第 2 页:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building1 | Human Resources

Name    |    Age
Ian          27
Justin       41

第 3 页:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building2 | Accounting

Name    |    Age
Mary         43

第 4 页:

// Repeat of Page 1's headers
Building1 | Finance

Name    |    Age

Building2 | ISS

Name    |    Age
Chris         43

【问题讨论】:

  • 您使用的是哪个浏览器?据我记得,Chrome 在每一页上打印标题都有问题。我不知道他们是否修复了它。
  • @jae.phoenix 我使用的是 IE 11。
  • 我不知道你是否已经有了,但是看看这个:link。据我了解,最重要的部分是在 thead 的每一页上添加您要打印的内容以及您正在使用的 css,以及 tbody 中的内容以及 css display:table-row-group;
  • @jae.phoenix 我已编辑我的问题以显示我的问题的更具体示例。
  • 如果你在你的桌子外面做你的for循环怎么办?这样它就会在每个循环中创建一个新表,而不仅仅是一个头部和一个身体。我认为正在发生的事情是表格中有多个头,这就是为什么它将每个头打印在每一页的顶部。

标签: html css printing


【解决方案1】:

尝试在 for 循环中创建表格,以便循环在每个循环上创建一个新表格,而不仅仅是头部和主体。所以我认为这正在发生:

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>

    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>

而不是这个

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>
</table>

<table>
    <thead>
    ...
    </thead>
    <tbody>
    ...
    </tbody>
</table>

所以发生的情况是您只有 1 个表格,并且它在每页顶部打印该表格内的每个头,因为该表格正在转到下一页。对于多个表格,它只包含头部,因此每次表格浮动到下一页时,头部都会打印在新页面的顶部。

然后您可以在每个 tbody 之前执行您的 if,因为看起来每个表中的头部都保持相同。

不妨试试这个:

        @foreach (var item in Model){

            <table class="table table-bordered no-border">

                <thead>
                    <tr>
                        <th><b>@item.Building</b></th>
                        <th><b>@item.Division</b></th>
                    </tr>


                    <tr class="no-display"></tr>
                    <tr>
                        <th>Name</th>
                    </tr>
                    <tr>
                        <th>Age</th>
                    </tr>
                </thead>

                <tbody>

                if ((Model.IndexOf(item) == 0) ||     ((Model.IndexOf(item) != 0) && (!item.Building.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Building) || !item.Division.Equals(Model.ElementAt(Model.IndexOf(item) - 1).Division)))){   
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                }
                else{
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Age)
                        </td>
                    </tr>
                }
                </tbody>

            </table>

        }

【讨论】:

  • 您发布的代码.. 如果我将表格放在 foreach 循环中.. 这将为每个项目创建一个新的 thead 元素.. 即使它们位于同一建筑物和分区中。 .我只想要每组人1个建筑和分区。
  • 如果您在头内的item 数组中添加索引会怎样
  • 什么意思?
  • 您的Model 是一个数组,对于该数组中的每个item,您要打印一个&lt;thead&gt;。所以现在在你的循环中,你指定要打印数组中的哪个项目。我认为它应该看起来像这样(不是 100% 确定)://这可以让您同时获得项目 (item.value) 及其索引 (item.i) @foreach (var item in Model((value,i) = > new {i, value})) {
  • 索引是@item.i,值是@item.Building
  • }
  • 也许你会更好地理解它。看看这个link
  • 【解决方案2】:

    Multiple thead in a single table 可能不可行。也就是说,您必须为每个要创建的广告创建一个新表。

    要在一个循环中完成此操作,如下所示:

    var lastBuilding = null, lastDivision = null;
    
    foreach(var item in Model) {
    
        if(!item.Building.Equals(lastBuilding) || !item.Division.Equals(lastDivision)) {
            if(lastBuilding != null && lastDivision != null) {
                </tbody></table>
            }
            <table>
                <thead>
                    <tr>
                        <th><b>@item.Building</b></th>
                        <th><b>@item.Division</b></th>
                    </tr>
                    <tr class="no-display"></tr>
                    <tr>
                        <th>Name</th>
                    </tr>
                    <tr>
                        <th>Age</th>
                    </tr>
                </thead>
                <tbody>
        }
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Age)
            </td>
        </tr>
        lastBuilding = item.Building;
        lastDivision = item.Division;
    }
    

    这里的逻辑关键是:

    1. Each item ultimately equates to a row in a table so the item outputs each iteration. The rest is just checking for whether or not a new table should be started (and the last one ended).
    2. Setting lastBuilding and lastDivision to null for the first iteration avoids the first table being ended immediately.
    

    【讨论】:

    • 即使&lt;/tbody&gt;&lt;/table&gt; 高于&lt;table&gt;?
    • 正确。由于封装了if,` 不会在第一个循环中执行,而是在下一个 之前执行。实际上是在打开下一个表之前关闭最后一个表。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签