我想根据表格(包括边框)绘制一个时间表,其中一些单元格(部分)用颜色填充。此颜色基于PdfTemplate,它作为图像添加到单元格中。
我为它创建了一个测试项目,并附加了输出:PDF output
在这个例子中,我希望它可以绘制实线,每次增加2个块。如您所见,它比2个块多一点。
我创建的模板应该与表格单元格的大小完全相同。所以我不明白,为什么它每次迭代都会变得越来越大。
任何想法如何解决这个问题?
public Test()
{
int cellWidth = 23;
int usernameCellWith = 86;
float[] scheduleTableColumnWidths = new float[33];
scheduleTableColumnWidths[0] = usernameCellWith;
for (int i = 1; i <= 32; i++)
scheduleTableColumnWidths[i] = cellWidth;
using (MemoryStream stream = new MemoryStream())
{
Rectangle rect = PageSize.GetRectangle("A4");
rect = new Rectangle(rect.Height, rect.Width, 90);
using (Document document = new Document(rect, 10f, 10f, 10f, 10f))
{
PdfWriter writer = PdfWriter.GetInstance(document, stream);
if (!document.IsOpen())
{
document.NewPage();
document.Open();
}
PdfPTable containerTable = new PdfPTable(1);
containerTable.DefaultCell.Border = Rectangle.NO_BORDER;
containerTable.WidthPercentage = 100;
PdfPTable scheduleTable = new PdfPTable(scheduleTableColumnWidths);
for (int iRow = 0; iRow <= 23; iRow++)
{
PdfPCell usernameCell = new PdfPCell(new Phrase("user "+ iRow));
usernameCell.FixedHeight = cellWidth;
scheduleTable.AddCell(usernameCell);
for (int iColumn = 1; iColumn <= 32; iColumn++)
{
PdfPCell cell = new PdfPCell();
cell.FixedHeight = cellWidth;
if (iColumn == 1 && iRow % 2 == 0)
{
float width = (float)(iRow + 1) * cellWidth;
PdfTemplate template = writer.DirectContent.CreateTemplate(width, cellWidth);
template.SetColorFill(new BaseColor(System.Drawing.ColorTranslator.FromHtml("#255C8A")));
template.Rectangle(0, 0, width, cellWidth);
template.Fill();
cell = new PdfPCell(Image.GetInstance(template));
}
scheduleTable.AddCell(cell);
}
scheduleTable.CompleteRow();
}
containerTable.AddCell(scheduleTable);
containerTable.CompleteRow();
document.Add(containerTable);
document.CloseDocument();
}
}
}
答案 0 :(得分:1)
你绝对需要使用PdfTemplate
吗?除非您刚刚发布了代码的简化版本,否则会尖叫使用colspan
,然后iText将为您计算所有内容。
以下是您发布的内容的修改版本。为了帮助我自己的心理过程,我将你的一些“神奇数字”移到了变量上。他们可能没有理想的名字,但他们做的工作。此外,在双for
循环中工作时,我建议始终循环遍历行和列,然后执行逻辑。您的代码循环遍历行,为“第一个单元格”执行某些逻辑,然后循环遍历列的子集并执行更多逻辑。虽然绝对100%有效,但我个人觉得它很混乱,特别是当必须在1和0之间跳跃作为起始值时。
另外,我强烈建议避免CompleteRow()
。它存在是为了解决某个问题,但它的字面意思是“我上面的逻辑可能是错的,所以iText,你能不能为我捏这些数字?”
我评论了我改变的大部分内容,所以希望这会有所帮助。
public void Test() {
int cellWidth = 23;
int usernameCellWith = 86;
int maxNumberOfColumns = 32;
int maxNumberOfRows = 24;
float[] scheduleTableColumnWidths = new float[maxNumberOfColumns];
scheduleTableColumnWidths[0] = usernameCellWith;
for (int i = 1; i < maxNumberOfColumns; i++)
scheduleTableColumnWidths[i] = cellWidth;
using (MemoryStream stream = new MemoryStream()) {
iTextSharp.text.Rectangle rect = PageSize.GetRectangle("A4");
rect = new iTextSharp.text.Rectangle(rect.Height, rect.Width, 90);
using (Document document = new Document(rect, 10f, 10f, 10f, 10f)) {
PdfWriter writer = PdfWriter.GetInstance(document, stream);
//Unless this code is just a sample, a new document is never open and NewPage() is implied so these four lines could just be document.Open();
if (!document.IsOpen()) {
document.NewPage();
document.Open();
}
PdfPTable containerTable = new PdfPTable(1);
containerTable.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
containerTable.WidthPercentage = 100;
PdfPTable scheduleTable = new PdfPTable(scheduleTableColumnWidths);
//Loop through each row
for (int iRow = 0; iRow < maxNumberOfRows; iRow++) {
//Loop through each column
for (int iColumn = 0; iColumn < maxNumberOfColumns; iColumn++) {
//Placeholder variable that will be instantiated within the if statements below
PdfPCell cell;
//On the first column (of every row)
if (0 == iColumn) {
cell = new PdfPCell(new Phrase("user " + iRow));
//On the second column of every other row starting with the first (zeroth) row
} else if ((iColumn == 1) && (iRow % 2 == 0)) {
cell = new PdfPCell();
//Have the cell span based on the current row number
cell.Colspan = iRow + 1;
//Set the color
cell.BackgroundColor = new BaseColor(System.Drawing.ColorTranslator.FromHtml("#255C8A"));
//Tell the inner for loop that we've accounted for some cells already
iColumn += iRow;
//Every other cell
} else {
cell = new PdfPCell();
}
//This is weird
cell.FixedHeight = cellWidth;
//Regardless of the above, add a cell
scheduleTable.AddCell(cell);
}
}
containerTable.AddCell(scheduleTable);
document.Add(containerTable);
document.CloseDocument();
}
}
}