我通过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();
}
非常感谢所有输入和帮助。感谢
答案 0 :(得分:3)
好的,有两种选择。
使用PdfContentByte和ColumnText手动绘制所有文本布局部分。
说服正常的iText布局代码,您的页面足够宽以容纳整行,然后将这些页面拆分成碎片。不漂亮,但可能比替代方案更容易。
首先,您需要定义比正常情况宽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();
该死的我很好。哦哦!谦虚!让我们不要忘记好看,勇敢,彬彬有礼,机智......