使用iTextSharp生成双平行表格PDF时遇空引用错误求助
解决iTextSharp生成左右双栏通讯录PDF的空引用错误与优化方案
首先,先帮你排查那个空引用错误的几个核心可能原因:
- 最终表格未初始化:你用来承载左右两个section表格的大表格,是不是忘记用
new PdfPTable(2)实例化了?如果这个变量是null,添加到Document时必然会抛出空引用异常。 - Section表格实例化遗漏:每次达到指定行数后,创建的section表格是不是没正确new出来?比如循环里如果section为null就调用
AddRow,肯定会触发错误。 - 空PdfPRow元素:从原表格拆分出的PdfPRow数组里有没有null值?迭代添加时要先判断
row != null再操作。 - Document状态异常:添加表格前一定要确认Document已经调用
Open()方法,未打开的文档也会抛出奇怪的引用错误。
接下来给你两种更简洁的实现思路,比手动拆分行的方式更可靠:
方案一:用ColumnText实现自动分栏(推荐)
iTextSharp的ColumnText可以自动处理内容的栏间流动,触达页面底部时自动切换到右栏,完全不用手动拆分行,非常适合通讯录这类列表场景:
// 初始化文档和Writer Document document = new Document(PageSize.A4, 20, 20, 20, 20); PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("PhoneBook.pdf", FileMode.Create)); document.Open(); // 创建基础通讯录单列表格(和你之前实现的一致) PdfPTable contactTable = new PdfPTable(1); contactTable.WidthPercentage = 100; // 添加表头 contactTable.AddCell(new PdfPCell(new Phrase("姓名"))); contactTable.AddCell(new PdfPCell(new Phrase("电话"))); // 假设contacts是从SQL获取的通讯录数据列表 foreach (var contact in contacts) { contactTable.AddCell(new PdfPCell(new Phrase(contact.Name))); contactTable.AddCell(new PdfPCell(new Phrase(contact.Phone))); } // 计算左右栏的宽度和位置 float columnWidth = (document.PageSize.Width - document.LeftMargin - document.RightMargin) / 2; float gap = 10; // 两栏之间的间距 // 处理左栏内容 ColumnText leftColumn = new ColumnText(writer.DirectContent); leftColumn.SetSimpleColumn( document.LeftMargin, document.BottomMargin, document.LeftMargin + columnWidth, document.TopMargin ); leftColumn.AddElement(contactTable); int flowStatus = leftColumn.Go(); // 如果左栏放不下,剩余内容自动流入右栏 if (flowStatus == ColumnText.NO_MORE_COLUMN) { ColumnText rightColumn = new ColumnText(writer.DirectContent); rightColumn.SetSimpleColumn( document.LeftMargin + columnWidth + gap, document.BottomMargin, document.PageSize.Width - document.RightMargin, document.TopMargin ); rightColumn.AddElement(leftColumn.RemainingElements); rightColumn.Go(); } document.Close();
方案二:手动拆分数据生成双栏表格
如果你坚持用拆分行的方式,要确保每一步的表格都正确实例化,避免空引用:
// 假设rows是你从原表格拆分出的PdfPRow数组 List<PdfPRow> rowList = new List<PdfPRow>(rows); int rowsPerColumn = 20; // 定义每栏显示的行数 PdfPTable mainTable = new PdfPTable(2); mainTable.WidthPercentage = 100; mainTable.SpacingBefore = 10; while (rowList.Count > 0) { // 创建左栏表格并添加行 PdfPTable leftTable = new PdfPTable(1); for (int i = 0; i < rowsPerColumn && rowList.Count > 0; i++) { leftTable.AddRow(rowList[0]); rowList.RemoveAt(0); } mainTable.AddCell(leftTable); // 创建右栏表格(如果还有剩余行) if (rowList.Count > 0) { PdfPTable rightTable = new PdfPTable(1); for (int i = 0; i < rowsPerColumn && rowList.Count > 0; i++) { rightTable.AddRow(rowList[0]); rowList.RemoveAt(0); } mainTable.AddCell(rightTable); } else { // 右栏无内容时添加空单元格占位 mainTable.AddCell(new PdfPCell()); } // 将当前双栏表格添加到文档,iTextSharp会自动处理分页 document.Add(mainTable); // 重置主表格,准备下一页的双栏内容 mainTable = new PdfPTable(2); }
最后再检查你的原有代码,确保所有涉及的表格变量都通过new完成实例化,没有null值的情况,应该就能解决那个空引用错误了。
内容的提问来源于stack exchange,提问作者Jacob Mich
相关产品推荐
相关产品推荐

