在使用 itextsharp 创建的 PDF table 中设置单元格高度
Set cell height in PDF table created with itextsharp
我使用以下代码在我的 itextsharp PDF 文档中创建了一个 table:
foreach (var subComp in competency.SubCompetensies)
{
cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
cell.Padding = 5;
cell.Rowspan = 2;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(0, subComp.Name, _nfSubComp));
cell.Colspan = 10;
cell.Padding = 5;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
cell.Padding = 5;
cell.Rowspan = 2;
table.AddCell(cell);
for (int i = 1; i < 11; i++)
{
cell = new PdfPCell(new Phrase(0, i.ToString(), _nfScale));
cell.FixedHeight = 15f;
cell.Padding = 3;
cell.PaddingLeft = 5;
table.AddCell(cell);
}
}
结果如下:
如您所见,每行带有数字的单元格的高度都不同。貌似cell.FixedHeight 属性被忽略了
有没有办法设置这些单元格的固定高度?
好吧,我找到了解决办法。至于我呢,好像有点小色狼,但是我的deadline根本不在乎我的代码有多精致
可能有人会发现它有用。
为什么 FixedHeight 被忽略了?
因为最后抽出数字的单元格连续消耗了所有空闲space。
可能的解决方案
我只能看到两种方式:
- 显然,改变一行中单元格的顺序
- 自己渲染行的中心部分
我决定选择第二种方式。
我没有使用 rowspans/colspans 创建十个单元格并将它们添加到一行,而是只添加了三个单元格:
cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
cell.MinimumHeight = 50;
cell.Padding = 5;
cell.BorderColor = BaseColor.WHITE;
cell.BackgroundColor = new BaseColor(233, 240, 242);
table.AddCell(cell);
cell = new PdfPCell();
cell.CellEvent = new CellEvents(subComp);
cell.BorderColor = BaseColor.WHITE;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
cell.Padding = 5;
cell.BorderColor = BaseColor.WHITE;
cell.BackgroundColor = new BaseColor(233, 240, 242);
table.AddCell(cell);
我将自定义单元格事件添加到第二次销售。它在设置单元格高度之后和布局渲染之前触发。这是事件处理程序的代码:
private class CellEvents : IPdfPCellEvent
{
public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
{
int scoreCellHeight = 20;
var pdfContentByte = canvases[0];
pdfContentByte.SaveState();
pdfContentByte.Rectangle(pos.Left, pos.Bottom + scoreCellHeight, pos.Width, pos.Height - scoreCellHeight);
pdfContentByte.SetColorFill(new BaseColor(233, 240, 242));
pdfContentByte.Fill();
ColumnText ct = new ColumnText(pdfContentByte);
ct.SetSimpleColumn(new Phrase(_model.Name, _nfSubComp), pos.Left, pos.Bottom + 20, pos.Left + pos.Width, pos.Bottom + pos.Height - 5, 10, Element.ALIGN_CENTER);
ct.Go();
float scaleWidth = pos.Width / 10;
for (int i = 1; i < 11; i++)
{
float scaleLeft = pos.Left + (i - 1) * pos.Width / 10;
pdfContentByte.Rectangle(scaleLeft, pos.Bottom, scaleWidth, scoreCellHeight);
pdfContentByte.SetColorFill(i % 2 == 1
? new BaseColor(Color.LightBlue)
: new BaseColor(233, 240, 242));
pdfContentByte.Fill();
ct.SetSimpleColumn(new Phrase(i.ToString(), _nfScale), scaleLeft, pos.Bottom,
scaleLeft + scaleWidth, pos.Bottom + 7, 0, Element.ALIGN_CENTER);
ct.Go();
}
canvases[0].RestoreState();
}
}
我跳过了一些细节,例如 class 构造函数和绘制标记(屏幕截图中的红色数字)的代码。
结果:
我想,这个解决方法不是最优的。但是我必须绘制一个红色标记,所以无论如何我都必须处理单元格渲染事件。
希望有人能给出正确的解决方案。
我使用以下代码在我的 itextsharp PDF 文档中创建了一个 table:
foreach (var subComp in competency.SubCompetensies)
{
cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
cell.Padding = 5;
cell.Rowspan = 2;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(0, subComp.Name, _nfSubComp));
cell.Colspan = 10;
cell.Padding = 5;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
cell.Padding = 5;
cell.Rowspan = 2;
table.AddCell(cell);
for (int i = 1; i < 11; i++)
{
cell = new PdfPCell(new Phrase(0, i.ToString(), _nfScale));
cell.FixedHeight = 15f;
cell.Padding = 3;
cell.PaddingLeft = 5;
table.AddCell(cell);
}
}
结果如下:
如您所见,每行带有数字的单元格的高度都不同。貌似cell.FixedHeight 属性被忽略了
有没有办法设置这些单元格的固定高度?
好吧,我找到了解决办法。至于我呢,好像有点小色狼,但是我的deadline根本不在乎我的代码有多精致
可能有人会发现它有用。
为什么 FixedHeight 被忽略了?
因为最后抽出数字的单元格连续消耗了所有空闲space。
可能的解决方案
我只能看到两种方式:
- 显然,改变一行中单元格的顺序
- 自己渲染行的中心部分
我决定选择第二种方式。 我没有使用 rowspans/colspans 创建十个单元格并将它们添加到一行,而是只添加了三个单元格:
cell = new PdfPCell(new Phrase(0, subComp.DescriptionMin, _nfDescr));
cell.MinimumHeight = 50;
cell.Padding = 5;
cell.BorderColor = BaseColor.WHITE;
cell.BackgroundColor = new BaseColor(233, 240, 242);
table.AddCell(cell);
cell = new PdfPCell();
cell.CellEvent = new CellEvents(subComp);
cell.BorderColor = BaseColor.WHITE;
table.AddCell(cell);
cell = new PdfPCell(new Phrase(subComp.DescriptionMax, _nfDescr));
cell.Padding = 5;
cell.BorderColor = BaseColor.WHITE;
cell.BackgroundColor = new BaseColor(233, 240, 242);
table.AddCell(cell);
我将自定义单元格事件添加到第二次销售。它在设置单元格高度之后和布局渲染之前触发。这是事件处理程序的代码:
private class CellEvents : IPdfPCellEvent
{
public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
{
int scoreCellHeight = 20;
var pdfContentByte = canvases[0];
pdfContentByte.SaveState();
pdfContentByte.Rectangle(pos.Left, pos.Bottom + scoreCellHeight, pos.Width, pos.Height - scoreCellHeight);
pdfContentByte.SetColorFill(new BaseColor(233, 240, 242));
pdfContentByte.Fill();
ColumnText ct = new ColumnText(pdfContentByte);
ct.SetSimpleColumn(new Phrase(_model.Name, _nfSubComp), pos.Left, pos.Bottom + 20, pos.Left + pos.Width, pos.Bottom + pos.Height - 5, 10, Element.ALIGN_CENTER);
ct.Go();
float scaleWidth = pos.Width / 10;
for (int i = 1; i < 11; i++)
{
float scaleLeft = pos.Left + (i - 1) * pos.Width / 10;
pdfContentByte.Rectangle(scaleLeft, pos.Bottom, scaleWidth, scoreCellHeight);
pdfContentByte.SetColorFill(i % 2 == 1
? new BaseColor(Color.LightBlue)
: new BaseColor(233, 240, 242));
pdfContentByte.Fill();
ct.SetSimpleColumn(new Phrase(i.ToString(), _nfScale), scaleLeft, pos.Bottom,
scaleLeft + scaleWidth, pos.Bottom + 7, 0, Element.ALIGN_CENTER);
ct.Go();
}
canvases[0].RestoreState();
}
}
我跳过了一些细节,例如 class 构造函数和绘制标记(屏幕截图中的红色数字)的代码。
结果:
我想,这个解决方法不是最优的。但是我必须绘制一个红色标记,所以无论如何我都必须处理单元格渲染事件。
希望有人能给出正确的解决方案。