一、引人眼球、唾弃无脑照搬
作者刚好用到的业务比较简单,没有用到图片,样式确实比较难调。
画pdf使用的是itext,这个东西好像是被收购过,不同版本的api有点不一样,不影响,测试的工具和项目中用的不一样。
<dependency>
<groupId>itext</groupId>
<artifactId>itext</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
不同版本用法差距不大,根据项目引入版本
Rectangle pageSize = new Rectangle(PageSize.A4.height(), PageSize.A4.width());
Rectangle pageSize = new Rectangle(PageSize.A4.getHeight(), PageSize.A4.getWidth());
二、正文分割线--------------------------------------------------------------------------------------
先demo,再项目
1、引入pom
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
2、引入字体 msyh.ttf
百度下载
3、xxxUtil.java
//定义全局变量 生成文件的名称和存放样式的地方
private final static String RESULT_FILE = "D:/abcd.pdf";
private final static String FONT_PATH = "D:/";
测试方法
//①建立com.lowagie.text.Document对象的实例。
Document doc = new Document();
//横着 竖着的话参数换个位置
Rectangle pageSize = new Rectangle(PageSize.A4.getHeight(), PageSize.A4.getWidth());
pageSize.rotate();
doc.setPageSize(pageSize);
//放样式的地
String fontPath = "D:/";
//②建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
PdfWriter.getInstance(doc, new FileOutputStream(RESULT_FILE));
//③打开文档。
doc.open();
Font myfont = CommonPDFUtil.setfont(FONT_PATH + "/msyh.ttf", 13.0F, 0, Color.BLACK, 0);// 基本字体
Font myfont3 = CommonPDFUtil.setfont(FONT_PATH + "/msyh.ttf", 18.0F, 0, Color.BLACK, 1);// 标头字体(三级字体)
Paragraph paragraph = new Paragraph("XXX系统发货单", myfont3);// 信用报告类型
paragraph.setAlignment(1);
doc.add(paragraph);
//这里是空白的地方搞这个
doc.add(new Paragraph(" ", myfont));
doc.add(new Paragraph(" ", myfont));
//注意注意 这里是画杠杠的 上文提到的低版本支持的一个杠杠方法高版本不支持 这里用更通用的 低版本有这个Graphic对象的
LineSeparator line = new LineSeparator(2f,100,Color.black,Element.ALIGN_CENTER,-5f);
doc.add(line);
//发货单 发货日期
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(PageSize.A4.getHeight()*0.9f);
table.setLockedWidth(true);
PdfPCell cell1 = null;
cell1 = new PdfPCell(new Phrase("发货单号:" + cSendoutDO.getSendoutNum(), myfont));
cell1.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
table.addCell(cell1);
cell1 = new PdfPCell(new Phrase("发货日期:" + DataCodeUtil.getYYYY_MM_DD(cSendoutDO.getSendoutDate()), myfont));
cell1.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
table.addCell(cell1);
doc.add(table);
//画一条杠杠
doc.add(line);
//关闭
doc.close();
设置样式的工具类
public class CommonPDFUtil {
//一条线
static final LineSeparator LINE = new LineSeparator(2f,100,Color.black,Element.ALIGN_CENTER,-5f);
// 设置字体
public static Font setfont(String fonttype, float fontsize, int fontflag, Color fontcolor, int fontstyle)
throws DocumentException, IOException {
BaseFont baseFont5 = BaseFont.createFont(fonttype, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Font font = new Font(baseFont5, fontsize, fontflag);
font.setColor(fontcolor);
if (fontstyle != 0) {// 如果传参为0不设置字体
font.setStyle(fontstyle);
}
return font;
}
}
为了代码简洁性 不按照图片写了 就说涉及到的知识
基本每行都用table是最好控制样式的 初始给table设置好列 比如两列 第三个cell就会在下一行
1)table.setWidths(new int[] { 9, 31, 15, 15,10,10,10 }); 设置列得宽度,按照比例分配的
2) table.setTotalWidth(PageSize.A4.getHeight()*0.9f); 表的宽度
table.setLockedWidth(true);分配宽度就得用这个锁住
3) cell.setHorizontalAlignment(Element.ALIGN_CENTER); 内容剧中的,去掉默认靠左
4)cell.setMinimumHeight(25); 调整下行间距
//再一个表
PdfPTable table = new PdfPTable(7);
PdfPCell cell = null;
table.setWidths(new int[] { 9, 31, 15, 15,10,10,10 });
table.setTotalWidth(PageSize.A4.getHeight()*0.9f);
table.setLockedWidth(true);
cell = new PdfPCell(new Phrase("序号", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
cell = new PdfPCell(new Phrase("生产厂家", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
cell = new PdfPCell(new Phrase("生产批号", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
cell = new PdfPCell(new Phrase("生产日期", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
cell = new PdfPCell(new Phrase("规模", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(20);
table.addCell(cell);
cell = new PdfPCell(new Phrase("箱数", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
cell = new PdfPCell(new Phrase("盒数", myfont));
cell.setBorder(PdfPCell.NO_BORDER);// Rectangle.NO_BORDER
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setMinimumHeight(25);
table.addCell(cell);
三、附加内容
作者参考的是这位大佬的,里面又页眉、页脚、插入图片
demo下载
待整理(里面涉及到了业务代码,最初的demo已经修改封装了)
四、springboot中应用
样式文件放resource还行,生成的pdf肯定放不了,运行起来也是target下了的。
//获取路径
String path = request.getSession().getServletContext().getRealPath("static");
本项目全部放到
生成且还得访问
1)获取路径
public class PathUtil {
public static String getPath() {
String path = null;
try {
path = ResourceUtils.getURL("").getPath();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return path;
}
}
2)springboot对外增加可以访问的目录
@Component
class WebConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//addResourceLocations指的是文件放置的目录,addResoureHandler指的是对外暴露的访问路径
String path=PathUtil.getPath()+"invoice/";
registry.addResourceHandler("/invoice/**").addResourceLocations("file:///"+path);
}
}
3)js访问
window.open(‘路径’, ‘_blank’).location;