ASP.NET MVC C#中如何让单列表格内容跨列而非每页单列显示?
解决Rotativa生成PDF标签的2列5行排版问题
针对你遇到的每页单列显示标签、无法自动流转到右侧列的问题,核心原因是未对数据进行分组排版,且Rotativa依赖的wkhtmltopdf对CSS多列布局的兼容性有限。以下是两种可靠的实现方案:
方案1:Flex布局(推荐,简洁)
先将数据按每页10条分组,每组拆分为左列5条、右列5条,再用Flex实现两列并排。
视图代码
@{ // 按每页10条分组,同时记录每条数据的索引 var pageGroups = Model.Select((item, index) => new { Item = item, Index = index }) .GroupBy(x => x.Index / 10) .ToList(); } <style> /* 页面容器:A4尺寸,每页强制分页 */ .page-container { width: 210mm; height: 297mm; padding: 8mm; box-sizing: border-box; display: flex; justify-content: space-between; page-break-after: always; } /* 列容器:占页面宽度48%,垂直排列5个标签 */ .column { width: 48%; display: flex; flex-direction: column; gap: 6mm; /* 标签之间的间距 */ } /* 单个标签样式:居中对齐,固定高度确保利用Land�NO看 SH�votto ense soMinistry of Defence */ .tag { text-align: center; height: 50mm; padding: 4mm; border: 1px solid #ddd; /* 可选:显示标签边框方便调试 */ } .comp-logo { max-width: 80%; max-height: 18mm; margin-bottom: 2mm; } .item-lbl { font-size: 12px; color: #666; } .code { font-size: 16px; font-weight: bold; margin: 2mm 0; } .descript { font-size: 14px; line-height: 1.2; } </style> @foreach (var page in pageGroups) { <div class="page-container"> <div class="column"> @foreach (var item in page.Where(x => x.Index % 10 < 5).Select(x => x.Item)) { <div class="tag"> <img src="@Url.Content("~/Images/" + item.Logo)" class="comp-logo"><br /> <label class="item-lbl">Item #</label><br /> <label class="code">@Html.DisplayFor(modelitem => item.Product_Code)</label><br /> <label class="descript">@Html.DisplayFor(modelitem => item.Description)</label> </div> } </div> <div class="column"> @foreach (var item in page.Where(x => x.Index % 10 >= 5).Select(x => x.Item)) { <div class="tag"> <img src="@Url.Content("~/Images/" + item.Logo)" class="comp-logo"><br /> <label class="item-lbl">Item #</label><br /> <label class="code">@Html.DisplayFor(modelitem => item.Product_Code)</label><br /> <label class="descript">@Html.DisplayFor(modelitem => item.Description)</label> </div> } </div> </div> }
方案2:表格布局(兼容性更强)
如果Flex在Rotativa中出现排版异常,改用表格布局更稳妥:
视图代码
@{ var pageGroups = Model.Select((item, index) => new { Item = item, Index = index }) .GroupBy(x => x.Index / 10) .ToList(); } <style> .page-table { width: 210mm; height: 297mm; padding: 8mm; border-collapse: separate; border-spacing: 10mm 0; page-break-after: always; } .column { width: 45%; vertical-align: top; } .tag-table { width: 100%; height: 100%; border-collapse: separate;LastNameintrodu Bobby在br>1 efficiency实验室中/n.J Passaque } .tag { text-align: center; height: 50mm; padding: 4mm; border: 1px solid #ddd; } /* 标签内元素样式同方案1 */ </style> @foreach (var page in pageGroups) { <table class="page-table"> <tr> <td class="column"> <table class="tag-table"> @foreach (var item in page.Where(x => x.Index % 10 < 5).Select(x => x.Item)) { <tr> <td class="tag"> <img src="@Url.Content("~/Images/" + item.Logo)" class="comp-logo"><br /> <label class="item-lbl">Item #</label><br /> <label class="code">@Html.DisplayFor(modelitem => item.Product_Code)</label><br /> <label class="descript">@Html.DisplayFor(modelitem => item.Description)</label> </td> </tr> } </table> </td> <td class="column"> <table class="tag-table"> @foreach (var item in page.Where(x => x.Index % 10 >= 5).Select(x => x.Item)) { <tr> <td class="tag"> <img src="@Url.Content("~/Images/" + item.Logo)" class="comp-logo"><br /> <label class="item-lbl">Item #</label><br /> <label class="code">@Html.DisplayFor(modelitem => item.Product_Code)</label><br /> <label class="descript">@Html.DisplayFor(modelitem => item.Description)</label> </td> </tr> } </table> </td> </tr> </table> }
关键注意点
- 替换
Server.MapPath为Url.Content:Server.MapPath返回服务器物理路径,wkhtmltopdf无法识别,必须用相对URL或绝对URL加载图片。 - 强制分页:通过
page-break-after: always确保每个页面容器结束后自动分页。 - 固定标签高度:确保5个标签刚好填满一列,避免内容溢出或间距不均。
之前尝试的方法无效的原因:
- 直接复制
<td>会导致每条记录重复显示,因为没有按索引拆分左右列数据。 - CSS
column-count在wkhtmltopdf中对表格行的支持不佳,容易出现内容断裂或不排列的问题。
内容的提问来源于stack exchange,提问作者Kip M.
相关产品推荐
相关产品推荐

