通过iTextSharp创建具有溢出布局的PDF

时间:2011-04-14 18:43:23

标签: c# asp.net itextsharp

我通过iTextSharp从DataTable成功创建PDF文档,但我无法以理想的格式获得布局。

虽然不太可能,但DataTable可能存在数十个列。想象一下下面的DataTable - 每个数字代表一个可以放在页面上的区域:

| ------------ |
| 1:2:3 |
| ------------ |
| 4:5:6 |
| ------------ |

这应该按照我对部分编号的顺序导出为6页的PDF文档。相反,它目前正在生成一个两页的文档,每个页面上有40多个列,并且字体很小,字面上没有细节。

解释我想要的最简单的方法是:当生成的PDF打印时,我希望它打印得像一张非常宽的Excel表格,而不是将所有内容压缩在一起。

我的代码如下:

    public static void ExportAsPDF(DataTable Table, IList<string> Columns, string filename)
    {
        int ColumnCount = Table.Columns.Count;
        int RowCount = Table.Rows.Count;

        iTextSharp.text.Table BodyTable = new iTextSharp.text.Table(ColumnCount, RowCount);
        BodyTable.AutoFillEmptyCells = true;

        foreach (string s in Columns)
        {
            BodyTable.AddCell(s);
        }
        foreach (object o in from DataRow row in Table.Rows from o in row.ItemArray select o)
        {
            BodyTable.AddCell(o.ToString());
        }

        Document doc = new Document();
        PdfWriter.GetInstance(doc, HttpContext.Current.Response.OutputStream);
        doc.Open();
        doc.Add(BodyTable);
        doc.Close();

        HttpContext.Current.Response.ContentType = "application/pdf";
        HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.pdf", filename));
        HttpContext.Current.Response.End(); 
    }

非常感谢所有输入和帮助。感谢

1 个答案:

答案 0 :(得分:3)

好的,有两种选择。

  1. 使用PdfContentByte和ColumnText手动绘制所有文本布局部分。

  2. 说服正常的iText布局代码,您的页面足够宽以容纳整行,然后将这些页面拆分成碎片。不漂亮,但可能比替代方案更容易。

  3. 首先,您需要定义比正常情况宽3倍的页面。

    Rectangle triplePageRect = new Rectangle(PageSize.LETTER);
    float origWidth = triplePageRect.getWidth();
    triplePageRect.setWidth(origWidth * 3f);
    
    Document doc = new Document(triplePageRect);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PdfWriter writer = PdfWriter.getInstance(doc, baos);
    

    然后你几乎就像现在一样绘制你的桌子......但是你必须确保一个列边缘与你的两个页面边缘对齐,以便你以后可以轻松地分解页面。如果您可以创建一个以分页符所在位置为中心的空行,那么您将获得一个保证金。

    //Your Code Here
    

    最后,您需要保存PDF,再次打开它,并将其切成丝带。我在想PdfStamper。

    // write everything out to the baos.
    doc.close(); 
    
    // and suck it right back up again.  Hurray for efficiency.  Or something.
    PdfReader reader = new PdfReader(baos.toByteArrayOrWhateverItsCalled());
    PdfStamper stamper = new PdfStamper( reader, new FileOutputStream(outputPath));
    
    // duplicate the pages.  I'll assume only one page, but you'll get the idea.
    PdfDictionary origPage = reader.getPageN(1);
    for (int i = 0; i < 2; ++i) {
      // initial size is irrelevant, we're going to change it, but !null
      stamper.insertPage(2+i, PageSize.LETTER); 
      PdfDictionary newPageDict = reader.getPage(2 + i);
    
      // copy the original page... note that this is a shallow copy
      newPageDict.putAll(origPageDict);
    
      // duplicate the page rect so each page will have its own copy
      PdfArray pageRect = newPageDict.getAsArray(PdfName.MEDIABOX);
      // also a shallow copy, but changes to this array will be localized to the page.
      PdfArray newRect = new PdfArray(pageRect);
      // page rects are defined as [llx lly urx ury], so we need to change 0 and 2.
      newRect.set(0, new PdfNumber(origWidth * (i+1));
      newRect.set(2, new PdfNumber(origWidth * (i+2));
    }
    
    //Smoke'em if you've got 'em folks, we're done.
    stamper.close();
    
    该死的我很好。哦哦!谦虚!让我们不要忘记好看,勇敢,彬彬有礼,机智......