使用iTextSharp导出DataGridView至PDF时实现列值变更分页
我来帮你实现这个按指定列值变化分页的需求!结合你现有的iTextSharp代码,咱们可以调整成下面这样,核心是监控目标列的数值变化,触发手动分页:
实现按指定列值变化分页的解决方案
首先,咱们先解决两个关键点:自动每页添加页眉(避免分页后新页面没有页眉)和检测列值变化触发分页。
1. 先定义页面事件处理类(处理每页页眉)
把你原来的Encabezado()逻辑移到这个事件类里,这样每一页都会自动生成页眉:
public class PdfHeaderHandler : PdfPageEventHelper { public override void OnStartPage(PdfWriter writer, Document document) { // 这里替换成你Encabezado()方法里的内容,比如添加页眉文本和分隔线 Paragraph header = new Paragraph("你的文档标题/页眉内容", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD)); header.Alignment = Element.ALIGN_CENTER; document.Add(header); // 添加页眉下方的分隔线 PdfContentByte contentByte = writer.DirectContent; contentByte.MoveTo(document.LeftMargin, document.Top - 25); contentByte.LineTo(document.RightMargin, document.Top - 25); contentByte.Stroke(); } }
2. 完整的导出代码(整合分页逻辑)
替换你原来的循环部分,核心是用PdfPTable管理表格,监控目标列的值变化:
using (FileStream stream = new FileStream(savefiledialoge.FileName, FileMode.Create)) { try { Document pdfdoc = new Document(PageSize.A4.Rotate(), 10f, 10f, 10f, 0f); PdfWriter writer = PdfWriter.GetInstance(pdfdoc, stream); // 绑定页眉事件,自动每页生成页眉 writer.PageEvent = new PdfHeaderHandler(); pdfdoc.Open(); // 配置:指定要监控的列索引(比如第2列,索引从0开始) int targetColumnIndex = 1; object previousColumnValue = null; PdfPTable currentTable = null; // 初始化第一个表格,添加表头 currentTable = new PdfPTable(dataGridView1.Columns.Count); currentTable.WidthPercentage = 100; // 表格占满页面宽度 foreach (DataGridViewColumn col in dataGridView1.Columns) { PdfPCell headerCell = new PdfPCell(new Phrase(col.HeaderText, new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD))); headerCell.BackgroundColor = BaseColor.LIGHT_GRAY; currentTable.AddCell(headerCell); } // 遍历DataGridView的每一行 foreach (DataGridViewRow row in dataGridView1.Rows) { // 跳过空白的新增行 if (row.IsNewRow) continue; object currentColumnValue = row.Cells[targetColumnIndex].Value; // 检测列值变化:如果不是第一行,且当前值和上一行不同,就分页 if (previousColumnValue != null && !currentColumnValue.Equals(previousColumnValue)) { // 将当前表格写入文档 pdfdoc.Add(currentTable); // 强制新建页面 pdfdoc.NewPage(); // 初始化新表格,重新添加表头 currentTable = new PdfPTable(dataGridView1.Columns.Count); currentTable.WidthPercentage = 100; foreach (DataGridViewColumn col in dataGridView1.Columns) { PdfPCell headerCell = new PdfPCell(new Phrase(col.HeaderText, new Font(Font.FontFamily.HELVETICA, 10, Font.BOLD))); headerCell.BackgroundColor = BaseColor.LIGHT_GRAY; currentTable.AddCell(headerCell); } } // 将当前行的单元格内容添加到表格 foreach (DataGridViewCell cell in row.Cells) { string cellContent = cell.Value?.ToString() ?? string.Empty; currentTable.AddCell(new Phrase(cellContent, new Font(Font.FontFamily.HELVETICA, 10))); } // 更新上一行的列值,用于下一次对比 previousColumnValue = currentColumnValue; } // 把最后一页的表格写入文档 if (currentTable != null) { pdfdoc.Add(currentTable); } pdfdoc.Close(); } catch (Exception ex) { // 这里可以添加异常处理逻辑,比如提示导出失败 MessageBox.Show($"导出失败:{ex.Message}"); } }
关键逻辑说明
- 表格管理:用
PdfPTable来统一管理表格内容,比手动绘制单元格更稳定,iTextSharp会自动处理表格内的分页(如果单组数据超过一页的话)。 - 分页触发:每次遍历行时,对比当前行目标列的值和上一行的值,一旦不同就将当前表格写入文档,新建页面并初始化新表格。
- 页眉处理:通过
PdfPageEventHelper实现每页自动添加页眉,不用手动在分页时重复调用Encabezado()。 - 空值处理:用
??运算符处理单元格值为null的情况,避免空引用异常。
内容的提问来源于stack exchange,提问作者drvfn
相关产品推荐
相关产品推荐

