2016-07-29 43 views
1

是否有建議使用包含段落的單元格構建表格以避免在將某個單元格添加到表格或表格到文檔時出現異常?我得到這個,我無法弄清楚發生了什麼:使用Windows控制檯項目iTextSharp 7未將對象引用設置爲對象的實例

[NullReferenceException: Object reference not set to an instance of an object.] 
    iText.Layout.Renderer.TableRenderer.DrawBorders(DrawContext drawContext) +2493 
    iText.Layout.Renderer.TableRenderer.DrawChildren(DrawContext drawContext) +1497 
    iText.Layout.Renderer.AbstractRenderer.Draw(DrawContext drawContext) +153 
    iText.Layout.Renderer.TableRenderer.Draw(DrawContext drawContext) +637 
    iText.Layout.Renderer.AbstractRenderer.DrawChildren(DrawContext drawContext) +104 
    iText.Layout.Renderer.BlockRenderer.Draw(DrawContext drawContext) +525 
    iText.Layout.Renderer.TableRenderer.DrawChildren(DrawContext drawContext) +1382 
    iText.Layout.Renderer.AbstractRenderer.Draw(DrawContext drawContext) +153 
    iText.Layout.Renderer.TableRenderer.Draw(DrawContext drawContext) +637 
    iText.Layout.Renderer.DocumentRenderer.FlushSingleRenderer(IRenderer resultRenderer) +473 
    iText.Layout.Renderer.RootRenderer.AddChild(IRenderer renderer) +1999 
    iText.Layout.RootElement`1.Add(BlockElement`1 element) +92 
    iText.Layout.Document.Add(BlockElement`1 element) +81 

這裏有一個簡單的快照(相對於真正的項目):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using iText.Layout; 
using iText.Layout.Borders; 
using iText.Layout.Element; 

namespace iTextTest 
{ 
    public static class iTextSharpHelper 
    { 
     public static T SetBorderEx<T>(this ElementPropertyContainer<T> element, Border border) 
      where T : ElementPropertyContainer<T> 
     { 
      element.SetBorder(border); 

      return (T)element; 
     } 

     public static Paragraph Style(this BlockElement<Paragraph> element) 
     { 
      element 
       .SetBorderEx(iText.Layout.Borders.Border.NO_BORDER) 
       .SetFont(iText.Kernel.Font.PdfFontFactory.CreateFont(iText.IO.Font.FontConstants.HELVETICA)) 
       .SetFontSize(10.0f) 
       .SetFixedLeading(12.0f) 
       .SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.BOTTOM) 
       .SetMargin(0f); 

      return (Paragraph)element; 
     } 
    } 

    class Program 
    { 
     private static float[] tableColumns = { 0.35f, 0.25f, 0.15f, 0.25f }; 

     static void Main(string[] args) 
     { 
      iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(new iText.Kernel.Pdf.PdfWriter("test.pdf")); 

      iText.Layout.Document document = new iText.Layout.Document(pdf, iText.Kernel.Geom.PageSize.A4); 

      document.SetMargins(50f, 50f, 25f, 50f); 

      iText.Layout.Element.Table mainTable = new iText.Layout.Element.Table(tableColumns) 
       .SetBorderEx(iText.Layout.Borders.Border.NO_BORDER) 
       .SetWidthPercent(100) 
       .SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.LEFT) 
       .SetPadding(0f); 

      for (int i = 0; i < 10; i++) 
      { 
       AddRow(mainTable, "ABCDEFGHIJ", "ABCDEFGHIJ", "ABCDEFGHIJ"); 
      } 

      document.Add(mainTable); 

      document.Close(); 
     } 

     private static void AddRow(iText.Layout.Element.Table table, string col1, string col2, string col3) 
     { 
      // Label 
      AddCell(table, col1, true) 
       .SetBorderTop(new iText.Layout.Borders.SolidBorder(iText.Kernel.Colors.Color.BLACK, 0.5f)); 

      // Product - Voucher and price/pcs   
      AddCell(table, col2, true) 
       .SetBorderTop(new iText.Layout.Borders.SolidBorder(iText.Kernel.Colors.Color.BLACK, 0.5f)); 

      // Message 
      AddCell(table, col3, true, 2) 
       .SetBorderTop(new iText.Layout.Borders.SolidBorder(iText.Kernel.Colors.Color.BLACK, 0.5f)) 
       //.SetBorderRight(new iText.Layout.Borders.SolidBorder(iText.Kernel.Colors.Color.BLACK, 0.5f)) 
       .SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.RIGHT) 
       .SetTextAlignment(iText.Layout.Properties.TextAlignment.RIGHT); 
     } 

     private static iText.Layout.Element.Cell AddCell(iText.Layout.Element.Table table, string text, bool setBold = false, int colSpan = 1) 
     { 
      iText.Layout.Element.Cell cell = new iText.Layout.Element.Cell(1, colSpan) 
       .SetBorderEx(iText.Layout.Borders.Border.NO_BORDER) 
       .SetVerticalAlignment(iText.Layout.Properties.VerticalAlignment.BOTTOM); 

      if (!string.IsNullOrEmpty(text)) 
      { 
      iText.Layout.Element.Paragraph paragraph = new iText.Layout.Element.Paragraph(text) 
       .Style(); 

      if (setBold) 
       paragraph.SetBold(); 

      cell.Add(paragraph); 
      } 

      table.AddCell(cell); 

      return cell; 
     } 
    } 
} 

注意,一個註釋掉代碼行:

//.SetBorderRight(new iText.Layout.Borders.SolidBorder(iText.Kernel.Colors.Color.BLACK, 0.5f)) 

添加它作爲一種解決方法,使文檔呈現無異常。

+0

我發現了一個問題。在這種情況下(它永遠不會發生,似乎取決於單元格的內容),我發現在設置無邊框後向右側和頂部添加邊框不會使其崩潰。只添加到頂部崩潰。這是網格中最右邊的單元格。可能與某些優化有關,以避免在不需要時打印邊界(這會重複它們...)? – mike

+0

你能分享示例代碼來重現問題嗎? – mkl

回答

2

鑑於OP添加的示例代碼,可以輕鬆地複製該問題。

此外,在將代碼移植到iText/Java之後,還可以在此處複製該問題,參見參考資料。測試方法testMikesCode。因此,它不會將Java(原始iText代碼)移植到C#中。

樣品甚至可以大大簡化並仍重現該問題:

try ( FileOutputStream target = new FileOutputStream("mikesTableIssueSimple.pdf"); 
     PdfWriter pdfWriter = new PdfWriter(target); 
     PdfDocument pdfDocument = new PdfDocument(pdfWriter) ) 
{ 
    Document document = new Document(pdfDocument); 
    Table mainTable = new Table(1); 
    Cell cell = new Cell() 
      .setBorder(Border.NO_BORDER) 
      //.setBorderRight(new SolidBorder(Color.BLACK, 0.5f)) 
      .setBorderTop(new SolidBorder(Color.BLACK, 0.5f)); 
    cell.add("TESCHTINK"); 
    mainTable.addCell(cell); 
    document.add(mainTable); 
} 

MikesTableIssue.java test method testSimplified

如果一個

  • 刪除setBorder(Border.NO_BORDER)
  • 不會發生此問題
  • 刪除setBorderTop(new SolidBorder(Color.BLACK, 0.5f))
  • 增加setBorderRight(new SolidBorder(Color.BLACK, 0.5f))

在這種情況下com.itextpdf.layout.renderer.TableRenderer.drawBorders(DrawContext)執行此代碼:

if (lastBorder != null) { 
    if (verticalBorders.get(j).size() > 0) { 
     if (i == 0) { 
      x2 += verticalBorders.get(j).get(i).getWidth()/2; 
     } else if(i == horizontalBorders.size() - 1 && verticalBorders.get(j).size() >= i - 1 && verticalBorders.get(j).get(i - 1) != null) { 
      x2 += verticalBorders.get(j).get(i - 1).getWidth()/2; 
     } 
    } 

    lastBorder.drawCellBorder(drawContext.getCanvas(), x1, y1, x2, y1); 
} 

lastBorderSolidBorder例如,verticalBorders[[null], [null]]j == 1i == 0

因此,一些額外的null檢查應該在這裏介紹。

相關問題