iText pdf表格画斜线
在使用iText输出pdf表格文件时,有时存在较复杂的报表样式,需要支持在表格中画斜线,支持斜线表头,
iText在单元格中画斜线采用PdfContentByte的lineTo方法,斜线的坐标位置是采用相对于Document的绝对位置,
并不是相对于单元格的相对位置.
单元格画斜线
1. 创建一个iText Document 对象,pdf文档大小设置为A4,通过PdfWriter对象获取PdfContentByte 对象为 canvas,
下面是通过canvas去画图形
Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, fos); writer.setViewerPreferences(PdfWriter.PageModeUseThumbs); document.setPageSize(PageSize.A4); document.open(); PdfContentByte canvas = writer.getDirectContent();
2. 创建一个PdfPTable 对象,Pdf Table需要指定每列的宽度,pdf的宽度=像素宽*0.75, 指定Table的总宽度,总宽度是每列宽度之和,
设置Table相对于Document居左对齐。
PdfPTable table = new PdfPTable(widths); table.setLockedWidth(true); table.setTotalWidth(458 * PDF_PERCENT); table.setHorizontalAlignment(Element.ALIGN_LEFT);
3. 画第一个单元格3个斜线,x1,y1,x2,y2,x3,y3为线的坐标终止位置,开始坐标为单元格开始位置,
LEFT=36,TOP=36,是PdfTable距离文档的左边距和上边距,而Pdf的y坐标位置是从底部开始计算的,所以第一个单元格的坐标位置是
document.getPageSize().getHeight() - TOP 与 LEFT, canvas.moveTo()单元格坐标位置,3条线分别lineTo()每个条线的终止坐标。
int x1 = 61, y1 = 77; int x2 = 132, y2 = 76; int x3 = 144, y3 = 31; float top = document.getPageSize().getHeight() - TOP; drawLine(canvas, LEFT, top, x1, y1); drawLine(canvas, LEFT, top, x2, y2); drawLine(canvas, LEFT, top, x3, y3); canvas.saveState(); canvas.moveTo(left, top); canvas.lineTo(left + x * PDF_PERCENT, top - y * PDF_PERCENT); canvas.stroke(); canvas.restoreState();
4. 画表头斜线坐标比较容易确定,如果画表格中间单元格的斜线需要计算单元格的坐标位置,如下cellX=第一列宽 + 第二列宽,
cellY = 第一行高 * PDF_PERCENT
int cellX = (int) (widths[0] + widths[1]); int cellY = (int) (77 * PDF_PERCENT); int x = 201, y = 84; drawLine(canvas, LEFT + cellX, top - cellY, x, y);
完整示例
下面是输出pdf斜线完整的示例代码,使用的iText类库为:itextpdf-5.5.1.jar
import java.awt.Color; import java.io.FileOutputStream; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Document; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; public class TestPdf { private static final float PDF_PERCENT = 0.75f; public static void main(String[] args) throws Exception { float[] widths = { 144 * PDF_PERCENT, 113 * PDF_PERCENT, 91 * PDF_PERCENT, 110 * PDF_PERCENT }; int TOP = 36, LEFT = 36; FileOutputStream fos = new FileOutputStream("D:/line.pdf"); Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, fos); writer.setViewerPreferences(PdfWriter.PageModeUseThumbs); document.setPageSize(PageSize.A4); document.open(); PdfContentByte canvas = writer.getDirectContent(); float top = document.getPageSize().getHeight() - TOP; PdfPTable table = new PdfPTable(widths); table.setLockedWidth(true); table.setTotalWidth(458 * PDF_PERCENT); table.setHorizontalAlignment(Element.ALIGN_LEFT); PdfPCell pdfCell = new PdfPCell(); final String text = " AB\n\n\n CD"; setBorderColor(pdfCell); pdfCell.setMinimumHeight(77 * PDF_PERCENT); pdfCell.setPhrase(new Paragraph(text, getPdfChineseFont())); table.addCell(pdfCell); // draw cell line int x1 = 61, y1 = 77; int x2 = 132, y2 = 76; int x3 = 144, y3 = 31; drawLine(canvas, LEFT, top, x1, y1); drawLine(canvas, LEFT, top, x2, y2); drawLine(canvas, LEFT, top, x3, y3); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setMinimumHeight(77 * PDF_PERCENT); table.addCell(pdfCell); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setMinimumHeight(77 * PDF_PERCENT); table.addCell(pdfCell); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setMinimumHeight(77 * PDF_PERCENT); table.addCell(pdfCell); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setMinimumHeight(83 * PDF_PERCENT); table.addCell(pdfCell); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setMinimumHeight(83 * PDF_PERCENT); table.addCell(pdfCell); pdfCell = new PdfPCell(); setBorderColor(pdfCell); pdfCell.setColspan(2); pdfCell.setMinimumHeight(83 * PDF_PERCENT); table.addCell(pdfCell); setBorderColor(pdfCell); int cellX = (int) (widths[0] + widths[1]); int cellY = (int) (77 * PDF_PERCENT); int x = 201, y = 84; drawLine(canvas, LEFT + cellX, top - cellY, x, y); document.add(table); document.close(); } // draw cell line private static void drawLine(PdfContentByte canvas, float left, float top, int x, int y) { canvas.saveState(); canvas.moveTo(left, top); canvas.lineTo(left + x * PDF_PERCENT, top - y * PDF_PERCENT); canvas.stroke(); canvas.restoreState(); } // 设置边框样式 public static void setBorderColor(PdfPCell pdfCell) { Color rgbColor = Color.BLACK; BaseColor baseColor = new BaseColor(rgbColor.getRed(), rgbColor.getGreen(), rgbColor .getBlue()); pdfCell.setBorderWidthTop(0.1f); pdfCell.setBorderWidthBottom(0.1f); pdfCell.setBorderWidthLeft(0.1f); pdfCell.setBorderWidthRight(0.1f); pdfCell.setBorderColorBottom(baseColor); pdfCell.setBorderColorLeft(baseColor); pdfCell.setBorderColorRight(baseColor); pdfCell.setBorderColorTop(baseColor); } public static Font getPdfChineseFont() throws Exception { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); return fontChinese; } }