如何使用虚线作为单元格边框?

我试图通过使用iText 2.1.0在表格中间获得虚线边框(使用的单元格边框)。 下面的代码即使在表格中间也会生成虚线边框。

你能帮我解决这个问题, 为特定的细胞单独添加活动吗?

import java.io.FileOutputStream; import com.lowagie.text.Cell; import com.lowagie.text.Document; import com.lowagie.text.PageSize; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPCellEvent; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfWriter; public class DottedLine { public static final String RESULT = "Dotted.pdf"; public static void main(String[] args) throws Exception { new DottedLine().createPdf(RESULT); } public void createPdf(String filename) throws Exception { Document document = new Document(PageSize.A4, 50, 50, 50, 50); PdfWriter.getInstance(document, new FileOutputStream(filename)); document.open(); PdfPTable tab = new PdfPTable(1); for (int j = 1; j <= 10; j++) { if (j == 5) { PdfPCell c1 = new PdfPCell(new Phrase("Test" + j)); c1.setBorder(Rectangle.TOP); c1.setCellEvent(new dot()); tab.addCell(c1); } else { PdfPCell c2 = new PdfPCell(new Phrase("Test " + j)); c2.setBorder(Rectangle.TOP); tab.addCell(c2); } } document.add(tab); document.close(); } // Cell Event to make dotted Line class dot implements PdfPCellEvent { @Override public void cellLayout(PdfPCell arg0, Rectangle arg1, PdfContentByte[] arg2) { arg0.setBorder(Rectangle.TOP); PdfContentByte cb = arg2[PdfPTable.LINECANVAS]; cb.setLineDash(3f, 3f); cb.restoreState(); } } } 

您正在使用单元格事件,但您的代码非常差。 您还引入了PDF语法错误,如果您只使用更新版本的iText,则会收到警告。 (关于过时的iText版本的警告是有原因的。人们不应该忽视它们!)

话虽这么说,我已经做了一个例子来解决你的问题: DottedLineCell

生成的PDF是一个包含两个表的文档: dotted_line_cell.pdf

对于第一个表,我们使用表事件:

 class DottedCells implements PdfPTableEvent { @Override public void tableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) { PdfContentByte canvas = canvases[PdfPTable.LINECANVAS]; canvas.setLineDash(3f, 3f); float llx = widths[0][0]; float urx = widths[0][widths[0].length -1]; for (int i = 0; i < heights.length; i++) { canvas.moveTo(llx, heights[i]); canvas.lineTo(urx, heights[i]); } for (int i = 0; i < widths.length; i++) { for (int j = 0; j < widths[i].length; j++) { canvas.moveTo(widths[i][j], heights[i]); canvas.lineTo(widths[i][j], heights[i+1]); } } canvas.stroke(); } } 

这是绘制单元格边框的最优雅方式,因为它只对所有行使用一个stroke()运算符。 如果你有带rowpans的表(但你可能不关心rowpans,因为你使用的是一个不支持rowpans的过时版本的iText),这不是一个选项。

第二个表使用单元格事件:

 class DottedCell implements PdfPCellEvent { @Override public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { PdfContentByte canvas = canvases[PdfPTable.LINECANVAS]; canvas.setLineDash(3f, 3f); canvas.rectangle(position.getLeft(), position.getBottom(), position.getWidth(), position.getHeight()); canvas.stroke(); } } 

对于单元格事件,在每个单元格周围绘制边框。 这意味着您将拥有多个stroke()运算符和重叠行。

我可以再次恳求你升级到更新的版本吗? pre-iText 5版本有一个特殊的错误,导致表行在十亿行中消失一次。