代码改变世界

记一次使用ItextSharp打印pdf

2019-07-20 18:11  mia_xie  阅读(1113)  评论(0)    收藏  举报

先看一眼设计图

如上图所示,【删除商品】的表还有好几个,展示不同的字和数据,需要根据条件判断是否显示,并支持分页带表头。所以如果数据量多的话,第二页不仅要带单据抬头,且每个表格要分页带表头。

主要实现方式是将整个单据的内容化作一个大的mainTable,然后商品和删除商品等作为mainTable中的无数个小table,每个table在定义时,使用Table.HeaderRows标记表头行数,如删除商品的表格,设置Table.HeaderRows=2,代表跨页后,会重复显示删除商品,及以下标题行,如下图所示:

另外一个要说的是文档最底部的说明文字,这个要求固定到文档最后一页的最底部,一开始是这样写的,

PdfContentByte cb1 = writer.DirectContent;
tableForRemind.WriteSelectedRows(0, -1, 35, 200, cb1);//35,200分别代表x,y轴坐标 座标系的原点为页面的左下角

tableForRemind是我定义的PdfTable,专门用来放最底下的固定文字,Itext分割文本到每页中,并将每个单词、句子等布置到页面上,但有时我们并不需要这种自动格式,有时我们希望将一些图象或者文本放置在某页的指定位置,为实现该功能,我们将使用PdfContentByte类。但是这样做有个问题,就是当第一页数据刚好放满,不需要分页时,底部说明会遮挡单据信息,于是想着能不能算出文档最后一页的剩余高度,如果不够放底部文字,则自动加一定高度的空行,使文档自动分页,代码如下:

public static float CalculateTableHeight(PdfPTable table)
{
using (MemoryStream ms = new MemoryStream())
{
using (Document doc = new Document(PageSize.A4))
{
using (PdfWriter w = PdfWriter.GetInstance(doc, ms))
{
doc.Open();

table.WriteSelectedRows(0, table.Rows.Count, 0, 0, w.DirectContent);

doc.Close();
return table.TotalHeight;
}
}
}
}

传入mainTable,模拟打印一遍,算出打印的table高度,再计算剩余高度,至此,需求效果是达到了,至于这种方法可不可取,不得而知,对ItextSharp研究还不够深,如有错误,还请留言!