文章目录
-
- 一、PDFbox说明
-
- 1、坐标
- 2、线
- 3、图
- 4、字
- 5、字体加载
- 6、jfreechart图表转字节数组
- 7、依赖
- 二、PDFbox样式
-
- 1、文字颜色
- 2、线颜色
- 3、线样式
- 三、工具类
-
- 边框样式
- 对齐样式
- 表
- 行
- 列
- 图片列
- pdf工具类
- 测试方法
- 四、效果图
一、PDFbox说明
1、坐标
文档左下角为坐标原点,x轴向右从0增加,y轴向上增加
2、线
以起始位置至终点一条线,线宽以垂直于起始至终止连线方向发散,例如线宽20,起始位置(0,10),终止位置(500,10)则线实际所占位置为(0,0),(0,20),(500,0),(500,20)所围成的长方形区域
3、图
图位置以左下角为原点向右上方发散
4、字
字的位置以左下角为原点向右上方发散
// 横线
contentStream.moveTo(0, 10);
contentStream.lineTo(540, 10);
contentStream.stroke();
// 竖线
contentStream.moveTo(10, 0);
contentStream.lineTo(10, 540);
contentStream.stroke();
// 斜线
contentStream.moveTo(0, 0);
contentStream.lineTo(540, 540);
contentStream.stroke();
// 图片
final byte[] imageByte = IOUtils.toByteArray(Objects.requireNonNull(DrawTableUtils.class.getClassLoader().getResourceAsStream("yellow.png")));
final PDImageXObject image = PDImageXObject.createFromByteArray(document, imageByte, "yellow.png");
contentStream.drawImage(image, 20, 0, 50, 50);
// 文字
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
contentStream.newLineAtOffset(0, 10);
String text = "This is the sample document and we are adding content to it.";
contentStream.showText(text);
contentStream.endText();
5、字体加载
1、ttf类型字体加载
InputStream inFont = DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
PDType0Font normalFont = PDType0Font.load(document, inFont);
PDType0Font boldFont = null;
2.otf类型字体加载
InputStream normalStream = DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
assert normalStream != null;
OpenTypeFont normalOtfFont = new OTFParser(false, true).parse(normalStream);
PDType0Font normalFont = PDType0Font.load(document, normalOtfFont, false);
6、jfreechart图表转字节数组
JFreeChart chart = new JFreeChart(title, xyplot);
// 图例字体清晰
chart.setTextAntiAlias(true);
chart.setBackgroundPaint(Color.WHITE);
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
BufferedImage bufferedImage = chart.createBufferedImage(600, 300);
byte[] bytes = ChartUtilities.encodeAsPNG(bufferedImage);
7、依赖
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.28</version>
</dependency>
二、PDFbox样式
1、文字颜色
Color color = new Color(255,0,0);
contentStream.setNonStrokingColor(color);
2、线颜色
Color color = new Color(255, 0, 0);
contentStream.setStrokingColor(color);
3、线样式
float[] a={
3,5};
contentStream.setLineDashPattern(a, 0);
contentStream.moveTo(0, 20);
contentStream.lineTo(540, 20);
contentStream.stroke();
contentStream.setLineDashPattern(a, 20);
contentStream.moveTo(0, 50);
contentStream.lineTo(540, 50);
contentStream.stroke();
float[] b={
3};
contentStream.setLineDashPattern(b, 20);
contentStream.moveTo(0, 80);
contentStream.lineTo(540, 80);
contentStream.stroke();
contentStream.setLineDashPattern(a, 0);
第一个参数 a={3,5} 3表明虚线宽度为3,5表明虚线间隔为5 。当a={3}时表明虚线宽度为3,间隔为3
第二个参数0表明虚线偏移量
三、工具类
边框样式
public enum BorderStyle {
SOLID(new float[]{
}, 0),
DOTTED(new float[]{
1}, 1),
DASHED(new float[]{
5,2}, 1);
private final float[] pattern;
private final int phase;
BorderStyle(float[] pattern, int phase) {
this.pattern = pattern;
this.phase = phase;
}
public float[] getPattern() {
return pattern;
}
public int getPhase() {
return phase;
}
}
对齐样式
public enum HorizontalAlignment {
LEFT, CENTER, RIGHT
}
表
@Data
public class PdfTable {
/**
* 行
*/
private List<PdfRow> rows;
/**
* 字体
*/
private String font;
public void addRow(PdfRow row){
rows.add(row);
}
}
行
@Data
@Builder
public class PdfRow {
/**
* 列
*/
private List<PdfColumn> pdfColumns;
/**
* 行高
*/
private float height;
/**
* 边框样式,仅下边框生效
*/
private BorderStyle borderStyle;
/**
* 边框颜色
*/
@Builder.Default
private Color boderColor=Color.BLACK;
/**
* 下边框是否生效
*/
private boolean downBorder;
public void addColumn(PdfColumn pdfColumn){
pdfColumns.add(pdfColumn);
}
}
列
@Data
@Builder
public class PdfColumn {
/**
* 背景颜色
*/
@Builder.Default
private Color backGround = Color.WHITE;
/**
* 边框颜色
*/
@Builder.Default
private Color borderColor = Color.BLACK;
/**
* 文字颜色
*/
@Builder.Default
private Color textColor= Color.BLACK;
/**
* 加粗
*/
@Builder.Default
private boolean block=false;
/**
* 文字大小
*/
@Builder.Default
private float fontSize=10F;
/**
* 偏移
*/
@Builder.Default
private float offset=0F;
/**
* 文字位置
*/
@Builder.Default
private HorizontalAlignment align =HorizontalAlignment.CENTER;
/**
* 自动宽度
*/
@Builder.Default
private boolean autoWidth=false;
/**
* 自动换行
*/
@Builder.Default
private boolean autoWidth=false;
/**
* 左边框
*/
private boolean leftBorder;
/**
* 右边框
*/
private boolean rightBorder;
/**
* 名称
*/
private String name;
/**
* 宽度,仅在自动宽度未生效时启用
*/
private float width;
/**
* 图片,图片生效时其他属性均不生效
*/
private PdfColumnImage columnImage;
}
图片列
@Data
@Builder
public class PdfColumnImage {
/**
* 图片名称/路径
*/
private String image;
/**
* x轴位置
*/
private float x;
/**
* y轴位置
*/
private float y;
/**
* 图片宽度
*/
private float width;
/**
* 图片高度
*/
private float height;
}
pdf工具类
public class DrawTableUtils {
/**
* 页边距
*/
private static final float PADDING = 30;
/**
* 下表格线偏移
*/
private static final float DOWN_LINE_PADDING = 0.5f;
/**
* 边框宽度
*/
private static final float BORDER_WIDTH = 1;
/**
* 生成PDF
*
* @param table pdf数据
* @throws IOException
*/
public static void createDocument(PdfTable table) throws IOException {
// 初始化文档
PDDocument document = new PDDocument();
final PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// 字体
String fontName = table.getFont();
InputStream inFont = org.bmc.DrawTableUtils.class.getClassLoader().getResourceAsStream(fontName);
PDType0Font font = PDType0Font.load(document, inFont);
// 页
int pageNum = 1;
// 初始化文档位置
org.bmc.DrawTableUtils.Position position = new org.bmc.DrawTableUtils.Position(PADDING, page.getMediaBox().getHeight() - PADDING, 0);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
for (PdfRow row : table.getRows()) {
// 分页
if (position.startY <= PADDING * 2) {
pageNum++;
PDPage pdPage = new PDPage(PDRectangle.A4);
document.addPage(pdPage);
position.startY = page.getMediaBox().getHeight() - PADDING;
contentStream.close();
contentStream = new PDPageContentStream(document, pdPage);
}
drawLine(row, document, contentStream, position, font);
if (row.isDownBorder()) {
drawDrownBorder(contentStream, page, row, position);
}
}
contentStream.close();
// 页脚
drawPageFoot(document, pageNum, font);
// 保存文档
document.save("D:/mypdf.pdf");
document.close();
}
/**
* 生成表格下框,以行为单位
*
* @param contentStream 流
* @param page 页
* @param row 行
* @param position 位置
* @throws IOException
*/
private static void drawDrownBorder(PDPageContentStream contentStream, PDPage page, PdfRow row, org.bmc.DrawTableUtils.Position position) throws IOException {
contentStream.