您的位置:首页 > 其它

<<iText in Action 2nd>>4.4 (Adding a table at an absolute position)读书笔记

2017-12-04 09:48 525 查看



前言

在第二节中我们创建了大量high-level的对象,iText会自动对其布局。在第三节的时候我们学会了writing to direct content,然后使用ColumnText对象将high-levl和lowel-level对象组合起来使用。目前为止我们将PdfPTable对象当作high-level对象使用,因此在其被添加到Document时:单元格的文本内容会被添加到文本层(text layer),其它所有的边框,背景色,图片都添加到文本层的下面。但是我们也可以将PdfPTable添加到文本层的上面抑或是图形层的下面。


Working with WriteSelectedRows()

下图是2011年的日历,背景是一张图片,而在背景前面是一个绝对定位的表格。





listing 4.21 PdfCalendar.cs
PdfPTable table;
Calendar calendar = CultureInfo.GetCultureInfo(LANGUAGE).Calendar;

PdfContentByte canvas = writer.DirectContent;
for (int month = 1; month <= 12; month++)
{

// draw the background
DrawImageAndText(canvas, month.ToString().PadLeft(2, '0'));
// create a table with 7 columns
table = new PdfPTable(7);
table.TotalWidth = 504;
// add the name of the month
table.DefaultCell.BackgroundColor = BaseColor.WHITE;
DateTime dt = new DateTime(YEAR, month, 1);
table.AddCell(GetMonthCell(dt));
int daysInMonth = DateTime.DaysInMonth(YEAR, month);
int day = 0;
int position = (int)calendar.GetDayOfWeek(dt);
// add empty cells
for (int j = 0; j < position; j++)
{
table.AddCell("");
}
// add cells for each day
do
{
DateTime oneDt = dt.AddDays(day);
day++;
table.AddCell(GetDayCell(calendar, oneDt));

} while (day < daysInMonth);

// complete the table
table.CompleteRow();
// write the table to an absolute position
table.WriteSelectedRows(0, -1, 169, table.TotalHeight + 18, canvas);

document.NewPage();
}


在我们将table绝对定位时一定要设置表格总的宽度(TotalWidth),而且我们也不需要将宽度锁定,因为iText会忽视WidthPercentage的属性(这个属性只有在通过Documnet.Add方法添加时才有效)。表格的绝对定位是通过WriteSelectedRows方法实现的,现在我们讨论下此方法的参数。


SELECTING THE ROWS AND THE TABLE POSITION

方法的前两个参数是表格的起始和结束列,0到-1表示添加所有的列,其中-1表示所有剩余的列。接下来的两个参数是表格绝对定位的左上角座标,因为希望表格不要离页面的下边距太近,我们在表格的高度上添加了18pt。最后一个参数就是要添加的PdfContentByte对象。


CONTENT CANVASES

除了单个的PdfContentByte对象,WriteSelectedRows方法还接受4个PdfContentByte对象组合的一个数组,其中每个PdfContentByte对象都有一个特定的名称和目的:
PdfPTable.BASECANVAS----添加到这里的内容会处于表格下面
PdfPTable.BACKGROUNDCANVAS----背景色的层
PdfPTable.LINECANVAS----线的层
PdfPTable.TEXTCANVAS----表格中文本的层,其会位于表格上面

如果只是传入一个PdfContentByte对象,则文本位于线上面,线位于背景色上面,背景色位于BaseCanvas上面。


SPLITTING A PDFPTABLE VERTICALLY

假设一个表格的列太多了导致一页不能完全显示,这个时候我们就可以将表格在水平面上分隔,就如下图:





上图是一个表格,其内容是张艺谋导演的电影,表格总的宽度设置为600pt,但页面可用的宽度只有595pt。因此使用了两次WriteSelectedRows方法来实现,具体参考以下代码:

listing 4.22 Zhang.cs
// Create a table and fill it with movies
List<Movie> movies = PojoFactory.GetMovies(conn, 3);
PdfPTable table = new PdfPTable(new float[] { 1, 5, 5, 1 });
foreach (Movie movie in movies)
{
table.AddCell(movie.Year.ToString());
table.AddCell(movie.Title);
table.AddCell(movie.OriginalTitle);
table.AddCell(movie.Duration.ToString());
}

// set the total width of the table
table.TotalWidth = 600;
PdfContentByte canvas = writer.DirectContent;

// draw the first three columns on one page
table.WriteSelectedRows(0, 2, 0, -1, 236, 806, canvas);
document.NewPage();
// draw the next three columns on the next page
table.WriteSelectedRows(2, -1, 0, -1, 36, 806, canvas);


在第一次调用WriteSelectedRows方法时我们将前两列添加到一页中,其它的列添加到下一页中。通过WriteSelectedRows方法可以将表格绝对定位,但还有一种绝对定位的方法:将PdfPTable对象包裹在ColumnText对象中。


Wrapping tables in columns

好了直接上图和代码:





listing 4.23 ColumnTable.cs
ColumnText column = new ColumnText(writer.DirectContent);
List<DateTime> days = PojoFactory.GetDays(conn);

float[,] x ={  { document .Left ,document .Left +380},
{ document .Right -380,document .Right }};

foreach (DateTime day in days)
{
// add content to the column
column.AddElement(GetTable(conn, day));
int count = 0;
float height = 0;
int status = ColumnText.NO_MORE_COLUMN;
// render the column as long as it has content
while (ColumnText.HasMoreText(status))
{
// add the top-level header to each new page
if (count == 0)
{
height = AddHeaderTable(document, day, writer.PageNumber);
}

// set the dimensions of the current column
column.SetSimpleColumn(x[count, 0], document.Bottom, x[count, 1], document.Top - height - 10);
// render as much content as possible
status = column.Go();
// go to a new page if you've reached the last column
if (++count > 1)
{
count = 0;
document.NewPage();
}
}
document.NewPage();
}


这里使用的是ColumnText对象的一些属性,比较简单就不详细解释。


总结

表格的绝对定位这里使用了两种方式:WriteSelectedRows方法和ColumnText对象,这两种方式都设计一些low-level的操作。这里第四节的内容就完全结束了,但对于PdfPTable和PdfPCell的讨论还要继续,下一节中我们会使用表格和单元格的事件进行更加完美的布局,最后是代码下载


同步

此文章已同步到目录索引:iText in Action 2nd 读书笔记。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐