用于 C# 的 iText PDF 版本 7 的问题
Problems with Version 7 of iText PDF for C#
我正在使用 iText PDF 生成包含 table 的 PDF 文件,其布局应如下所示:
------------------------------------------------
| HEADER |
------------------------------------------------
| some data goes here | more data here |
------------------------------------------------
| Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | Col 6 |
------------------------------------------------
| 1 | SDF wer qwerwq | weqr | WERQW |
------------------------------------------------
| | | | |
| | | | |
| | | | |
| | | | |
------------------------------------------------
| footer information |
------------------------------------------------
但是 table 绘制如下:
------------------------------------------------
| HEADER |
------------------------------------------------
| some data goes here | more data here |
------------------------------------------------
| Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | Col 6 |
------------------------------------------------
| 1 | SDF | wer | qwerwq | weqr | WERQW |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| footer information |
------------------------------------------------
我尝试按照示例进行操作,但它们是用 Java 编写的,C# 的 Object 模型似乎略有不同。 "Col 1" 值为 1 的行下方的行拆分为第 2、3 和 4 列。
注意事项:
- 对于 header 单元格,我通过调用 cell.SetHorizontalAlignment(HorizontalAlignment.CENTER)
设置水平对齐方式
- 我需要将一些文字的颜色设置为红色
- 我正在使用 table.AddCell 方法添加单元格
- 我正在将 table 的边框(根据文档,这是默认单元格)设置为 Border.NO_BORDER。
- 这是用 C# 编写的网络应用程序
- 我已经下载了最新版的iText(7.0.1版)
- 我创建了自定义 CellRender,但似乎没有效果。
- 最初我使用的是 iText 5,但我需要更好地控制 table 的呈现,因为我需要知道我们到达了页面的底部。
这是我用来创建单元格的代码:
PdfFont cellFont = font;
if ((fontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD && (fontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC)
{
cellFont = fontBoldItalic;
}
else if ((fontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD)
{
cellFont = fontBold;
}
else if ((fontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC)
{
cellFont = fontItalic;
}
Color fontColor = Color.BLACK;
if ((fontStyle & FONT_STYLE_RED) == FONT_STYLE_RED)
{
fontColor = Color.RED;
}
Text text = new Text(content);
text.SetFont(cellFont);
text.SetFontColor(fontColor);
text.SetFontSize(fontSize);
if ((fontStyle & FONT_STYLE_UNDERLINE) == FONT_STYLE_UNDERLINE)
{
text.SetUnderline();
}
Cell cell = new Cell(rowspan, colspan);
cell.Add(new Paragraph(text));
//cell.SetNextRenderer(new CellBorders(cell, borders));
return cell;
这是创建 table 并将 table 添加到网络方法末尾的文档的方式:
Table table = new Table(6);
table.SetWidthPercent(100);
table.SetPadding(3);
table.SetSpacingRatio(1);
table.SetBorder(Border.NO_BORDER);
你这里有两个问题:
文本未正确对齐(页眉)
使用 SetTextAlignment()
方法设置单元格中的文本对齐方式。 SetHorizontalAlignment
设置容器包装文本的对齐方式。
边框未按预期显示。
首先,在 table 上定义边框并没有像在 iText 5 中那样定义 iText 7 中的默认单元格行为。由于默认的 tableRenderer 不使用边框 属性, table#SetBorder(Border.NO_BORDER)
将无效,除非您定义自定义渲染器并自己使用 属性。
定义自定义边框的正确方法是在单个单元格级别上进行。并且这里需要记住,由于边框重叠,如果不希望边框显示,需要将所有重叠的边框设置为NO_BORDER:
for(int j = 0; j<3; j++){
Cell dCell = new Cell();
//When setting borders to NO_BORDER, remember to set that border to NO_BORDER in all adjoining cells
dCell.SetBorderLeft(Border.NO_BORDER);
dCell.SetBorderRight(Border.NO_BORDER);
dCell.Add(new Paragraph(String.Format("Entry, {0}-{1}",i,j)));
//Dashed, striped, grooved and more can be specified
if(i != 4) dCell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(dCell);
}
以上片段将导致单元格在条目之间没有边框。
for(int k = 4; k<6;k++){
Cell d2Cell = new Cell();
//Only the right-most border will not show, since the left-most borders of the neighbouring cells still get drawn
d2Cell.SetBorderRight(Border.NO_BORDER);
d2Cell.Add(new Paragraph(String.Format("Entry, {0}-{1}",i,k)).SetFontColor(Color.RED));
//Specific borders apart from NO_BORDER do override the default
if(i!=4) d2Cell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(d2Cell);
}
以上片段只会在最右边的单元格右侧没有边框。
下面是一个独立的代码片段,它构造了一个 table 就像问题中的那个:
public void CreateTable(string dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
Table tab = new Table(6);
//Table should take up the entire width
tab.SetWidthPercent(100);
tab.SetPadding(3);
//Because table takes up the entire width, this has no visual effect, but otherwise it will center the table
tab.SetHorizontalAlignment(HorizontalAlignment.CENTER);
//Header cell
Cell hCell = new Cell(1, 6);
hCell.Add(new Paragraph("Centered Header"));
//Text is aligned by calling SetTextAlignment
hCell.SetTextAlignment(TextAlignment.CENTER);
tab.AddCell(hCell);
//Subheaders
Cell shCellL = new Cell(1, 3);
shCellL.Add(new Paragraph("Left aligned data"));
shCellL.SetTextAlignment(TextAlignment.LEFT);
Cell shCellR = new Cell(1, 3);
shCellR.Add(new Paragraph("Right aligned data"));
shCellR.SetTextAlignment(TextAlignment.RIGHT);
tab.AddCell(shCellL);
tab.AddCell(shCellR);
//col names
for (int i = 0; i < 6; i++)
{
Cell colName = new Cell();
colName.Add(new Paragraph(String.Format("Col {0}", i)));
colName.SetTextAlignment(TextAlignment.CENTER);
tab.AddCell(colName);
}
//data cols
for (int i = 1; i < 5; i++)
{
Cell nC = new Cell();
nC.Add(new Paragraph("" + i));
tab.AddCell(nC);
for (int j = 0; j < 3; j++)
{
Cell dCell = new Cell();
//When Setting borders to NO_BORDER, remember to Set that border to NO_BORDER in all adjoining cells
dCell.SetBorderLeft(Border.NO_BORDER);
dCell.SetBorderRight(Border.NO_BORDER);
dCell.Add(new Paragraph(String.Format("Entry, {0}-{1}", i, j)));
//Dashed, striped, grooved and more can be specified
if (i != 4) dCell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(dCell);
}
for (int k = 4; k < 6; k++)
{
Cell d2Cell = new Cell();
//Only the rightmost border will not show, since the left-most borders of the neighbouring cells still get drawn
d2Cell.SetBorderRight(Border.NO_BORDER);
d2Cell.Add(new Paragraph(String.Format("Entry, {0}-{1}", i, k)).SetFontColor(Color.RED));
//Specific borders apart from NO_BORDER do override the default
if (i != 4) d2Cell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(d2Cell);
}
}
//footer cell
Cell fCell = new Cell(1, 6);
fCell.Add(new Paragraph("footer"));
tab.AddCell(fCell);
//Add table to document
doc.Add(new Paragraph("Complex Table example"));
doc.Add(tab);
doc.Close();
}
我正在使用 iText PDF 生成包含 table 的 PDF 文件,其布局应如下所示:
------------------------------------------------
| HEADER |
------------------------------------------------
| some data goes here | more data here |
------------------------------------------------
| Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | Col 6 |
------------------------------------------------
| 1 | SDF wer qwerwq | weqr | WERQW |
------------------------------------------------
| | | | |
| | | | |
| | | | |
| | | | |
------------------------------------------------
| footer information |
------------------------------------------------
但是 table 绘制如下:
------------------------------------------------
| HEADER |
------------------------------------------------
| some data goes here | more data here |
------------------------------------------------
| Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | Col 6 |
------------------------------------------------
| 1 | SDF | wer | qwerwq | weqr | WERQW |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| | | | |
------------------------------------------------
| footer information |
------------------------------------------------
我尝试按照示例进行操作,但它们是用 Java 编写的,C# 的 Object 模型似乎略有不同。 "Col 1" 值为 1 的行下方的行拆分为第 2、3 和 4 列。
注意事项:
- 对于 header 单元格,我通过调用 cell.SetHorizontalAlignment(HorizontalAlignment.CENTER) 设置水平对齐方式
- 我需要将一些文字的颜色设置为红色
- 我正在使用 table.AddCell 方法添加单元格
- 我正在将 table 的边框(根据文档,这是默认单元格)设置为 Border.NO_BORDER。
- 这是用 C# 编写的网络应用程序
- 我已经下载了最新版的iText(7.0.1版)
- 我创建了自定义 CellRender,但似乎没有效果。
- 最初我使用的是 iText 5,但我需要更好地控制 table 的呈现,因为我需要知道我们到达了页面的底部。
这是我用来创建单元格的代码:
PdfFont cellFont = font; if ((fontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD && (fontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC) { cellFont = fontBoldItalic; } else if ((fontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD) { cellFont = fontBold; } else if ((fontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC) { cellFont = fontItalic; } Color fontColor = Color.BLACK; if ((fontStyle & FONT_STYLE_RED) == FONT_STYLE_RED) { fontColor = Color.RED; } Text text = new Text(content); text.SetFont(cellFont); text.SetFontColor(fontColor); text.SetFontSize(fontSize); if ((fontStyle & FONT_STYLE_UNDERLINE) == FONT_STYLE_UNDERLINE) { text.SetUnderline(); } Cell cell = new Cell(rowspan, colspan); cell.Add(new Paragraph(text)); //cell.SetNextRenderer(new CellBorders(cell, borders)); return cell;
这是创建 table 并将 table 添加到网络方法末尾的文档的方式:
Table table = new Table(6);
table.SetWidthPercent(100);
table.SetPadding(3);
table.SetSpacingRatio(1);
table.SetBorder(Border.NO_BORDER);
你这里有两个问题:
文本未正确对齐(页眉) 使用
SetTextAlignment()
方法设置单元格中的文本对齐方式。SetHorizontalAlignment
设置容器包装文本的对齐方式。边框未按预期显示。 首先,在 table 上定义边框并没有像在 iText 5 中那样定义 iText 7 中的默认单元格行为。由于默认的 tableRenderer 不使用边框 属性,
table#SetBorder(Border.NO_BORDER)
将无效,除非您定义自定义渲染器并自己使用 属性。
定义自定义边框的正确方法是在单个单元格级别上进行。并且这里需要记住,由于边框重叠,如果不希望边框显示,需要将所有重叠的边框设置为NO_BORDER:
for(int j = 0; j<3; j++){
Cell dCell = new Cell();
//When setting borders to NO_BORDER, remember to set that border to NO_BORDER in all adjoining cells
dCell.SetBorderLeft(Border.NO_BORDER);
dCell.SetBorderRight(Border.NO_BORDER);
dCell.Add(new Paragraph(String.Format("Entry, {0}-{1}",i,j)));
//Dashed, striped, grooved and more can be specified
if(i != 4) dCell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(dCell);
}
以上片段将导致单元格在条目之间没有边框。
for(int k = 4; k<6;k++){
Cell d2Cell = new Cell();
//Only the right-most border will not show, since the left-most borders of the neighbouring cells still get drawn
d2Cell.SetBorderRight(Border.NO_BORDER);
d2Cell.Add(new Paragraph(String.Format("Entry, {0}-{1}",i,k)).SetFontColor(Color.RED));
//Specific borders apart from NO_BORDER do override the default
if(i!=4) d2Cell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(d2Cell);
}
以上片段只会在最右边的单元格右侧没有边框。
下面是一个独立的代码片段,它构造了一个 table 就像问题中的那个:
public void CreateTable(string dest)
{
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
Table tab = new Table(6);
//Table should take up the entire width
tab.SetWidthPercent(100);
tab.SetPadding(3);
//Because table takes up the entire width, this has no visual effect, but otherwise it will center the table
tab.SetHorizontalAlignment(HorizontalAlignment.CENTER);
//Header cell
Cell hCell = new Cell(1, 6);
hCell.Add(new Paragraph("Centered Header"));
//Text is aligned by calling SetTextAlignment
hCell.SetTextAlignment(TextAlignment.CENTER);
tab.AddCell(hCell);
//Subheaders
Cell shCellL = new Cell(1, 3);
shCellL.Add(new Paragraph("Left aligned data"));
shCellL.SetTextAlignment(TextAlignment.LEFT);
Cell shCellR = new Cell(1, 3);
shCellR.Add(new Paragraph("Right aligned data"));
shCellR.SetTextAlignment(TextAlignment.RIGHT);
tab.AddCell(shCellL);
tab.AddCell(shCellR);
//col names
for (int i = 0; i < 6; i++)
{
Cell colName = new Cell();
colName.Add(new Paragraph(String.Format("Col {0}", i)));
colName.SetTextAlignment(TextAlignment.CENTER);
tab.AddCell(colName);
}
//data cols
for (int i = 1; i < 5; i++)
{
Cell nC = new Cell();
nC.Add(new Paragraph("" + i));
tab.AddCell(nC);
for (int j = 0; j < 3; j++)
{
Cell dCell = new Cell();
//When Setting borders to NO_BORDER, remember to Set that border to NO_BORDER in all adjoining cells
dCell.SetBorderLeft(Border.NO_BORDER);
dCell.SetBorderRight(Border.NO_BORDER);
dCell.Add(new Paragraph(String.Format("Entry, {0}-{1}", i, j)));
//Dashed, striped, grooved and more can be specified
if (i != 4) dCell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(dCell);
}
for (int k = 4; k < 6; k++)
{
Cell d2Cell = new Cell();
//Only the rightmost border will not show, since the left-most borders of the neighbouring cells still get drawn
d2Cell.SetBorderRight(Border.NO_BORDER);
d2Cell.Add(new Paragraph(String.Format("Entry, {0}-{1}", i, k)).SetFontColor(Color.RED));
//Specific borders apart from NO_BORDER do override the default
if (i != 4) d2Cell.SetBorderBottom(new DashedBorder(1f));
tab.AddCell(d2Cell);
}
}
//footer cell
Cell fCell = new Cell(1, 6);
fCell.Add(new Paragraph("footer"));
tab.AddCell(fCell);
//Add table to document
doc.Add(new Paragraph("Complex Table example"));
doc.Add(tab);
doc.Close();
}