一、java按照模板导出pdf
(一)制作模板
1、在word里制作模板
因为PDF常用的软件不支持编辑,所以先用Word工具,如WPS或者Office新建一个空白Word文档,里面制作出自己想要的样式。
2、 将Word转换成PDF形式
将设置好的Word文档转换成PDF形式,保存起来。
3、编辑PDF准备表单
用Adobe Acrobat DC 软件打开保存好的PDF模板文件,点击右侧的准备表单按钮
接下来进行数据源配置,在要显示图像的区域,点击鼠标右键,选择文本域,设定好图像的显示位置,并指定数据源字段。需要注意的是,配置的数据源字段必须与Java中的实体类对象的字段名保持一致。
配置完成之后保存pdf文件,留作模板使用。
(二)java代码编写
1、导入依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2、实体类
import lombok.Data;
/**
* 报表实体类
*/
@Data
public class MsaBusinessVO {
/**接收业务总次数*/
private String total;
/**接收业务总次数(去年同期)*/
private String lastToatl;
/**处理次数*/
private String dealNum;
/**处理次数(去年同期)*/
private String lastDealNum;
/**已完成次数*/
private String completeNum;
/**已完成次数(去年同期)*/
private String lastCompleteNum;
/**售后次数*/
private String afterSales;
/**售后次数(去年同期)*/
private String lastAfterSales;
}
3、service层代码实现
/**
* 生成报表
* @param id
* @param response
*/
void generateMsaBusiness(String id,HttpServletResponse response) throws UnsupportedEncodingException;
@Override
public void generateMsaBusiness(String id,HttpServletResponse response) throws UnsupportedEncodingException {
//通过id获取msaBusinessVO
MsaBusinessVO msaBusinessVO = msaBusinessDao.getMsaBusinessInfo(id);
// 模板名称
String templateName = "msaBusiness.pdf";
String path = "/static/template/";
//String path = "";
// 获取操作系统名称,根据系统名称确定模板存放的路径
/*String systemName = System.getProperty("os.name");
if(systemName.toUpperCase().startsWith("WIN")){
path = "D:/pdf/";
}else {
path = "/usr/local/pdf/";
}*/
// 生成导出PDF的文件名称
String fileName = "海事行政执法业务数据统计"+msaBusinessVO.getStartDate()+"至"+msaBusinessVO.getEndDate()+".pdf";
fileName = URLEncoder.encode(fileName, "UTF-8");
// 设置响应头
response.setContentType("application/force-download");
response.setHeader("Content-Disposition",
"attachment;fileName=" + fileName);
OutputStream out = null;
ByteArrayOutputStream bos = null;
PdfStamper stamper = null;
PdfReader reader = null;
try {
// 保存到本地
// out = new FileOutputStream(fileName);
// 输出到浏览器端
out = response.getOutputStream();
// 读取PDF模板表单
reader = new PdfReader(path + templateName);
// 字节数组流,用来缓存文件流
bos = new ByteArrayOutputStream();
// 根据模板表单生成一个新的PDF
stamper = new PdfStamper(reader, bos);
// 获取新生成的PDF表单
AcroFields form = stamper.getAcroFields();
// 给表单生成中文字体,这里采用系统字体,不设置的话,中文显示会有问题
//BaseFont font = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
BaseFont bf = BaseFont.createFont("/static/fonts/simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
form.addSubstitutionFont(bf);
// 装配数据
this.setMsaBusinessToForm(form, msaBusinessVO);
// 表明该PDF不可修改
stamper.setFormFlattening(true);
// 关闭资源
stamper.close();
// 将ByteArray字节数组中的流输出到out中(即输出到浏览器)
Document doc = new Document();
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
//改成这样就不会只显示一页了。
PdfImportedPage importPage = null;
///循环是处理成品只显示一页的问题
for (int i=1;i<=reader.getNumberOfPages();i++){
importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), i);
copy.addPage(importPage);
}
doc.close();
log.info("*****************************PDF导出成功*********************************");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.flush();
out.close();
}
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 装配数据
* @param form
* @param msaBusinessVO
* @throws DocumentException
* @throws IOException
*/
public void setMsaBusinessToForm(AcroFields form,MsaBusinessVO msaBusinessVO) throws DocumentException, IOException {
form.setField("total",msaBusinessVO.getTotal());//进出港船舶总艘次
form.setField("lastTotal",msaBusinessVO.getLastTotal());//进出港船舶总艘次(去年同期)
form.setField("dealNum",msaBusinessVO.getDealNum());//进出港报告内河船艘次
form.setField("lastDealNum",msaBusinessVO.getLastDealNum());//进出港报告内河船艘次(去年同期)
form.setField("completeNum",msaBusinessVO.getCompleteNum());//进出港报告海船艘次
form.setField("lastCompleteNum",msaBusinessVO.getLastCompleteNum());//进出港报告海船艘次(去年同期)
form.setField("afterSales",msaBusinessVO.getAfterSales());//进出口岸查验船舶艘次
form.setField("lastAfterSales",msaBusinessVO.getLastAfterSales());//进出口岸查验船舶艘次(去年同期)
}
4、Controller层代码实现
/**
* 导出pdf
* @param id
* @param response
*/
@GetMapping("/generateMsaBusiness")
public void generateMsaBusiness(String id,HttpServletResponse response){
try {
msaBusinessService.generateMsaBusiness(id,response);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
二、java按照模板导出word
(一)制作模板
1、word模板文件处理,如下图所示在word 文档中填值的地方写入占位变量,值得注意的是,word中的占位变量要与java代码中写入的元素名称保持一致。
2、将word文档另存为xml文件,编辑如下图,找到填写的占位,修改为${total}格式
3、将文件后缀名改为.ftl文件 ,留作模板使用。
(二)java代码编写
1、引入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
<scope>compile</scope>
</dependency>
2、service层代码实现
/**
* 导出word
* @param param
*/
void exportSimpleWord(Map<String,Object> param);
/**
* 保存打印记录
* @param param
* Map<String,Object> param 中的字段要与模板中的占位符名称一致
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void exportSimpleWord(Map<String,Object> param){
//param.put("total",total);
//param.put("lastTotal",lastTotal);
try {
// 要填充的数据 dataMap, 注意map的key要和word中${xxx}的xxx一致
//Configuration用于读取ftl文件
Configuration configuration = new freemarker.template.Configuration(Configuration.VERSION_2_3_23);
System.out.println(configuration.getVersion());
configuration.setDefaultEncoding("utf-8");
//指定路径的第一种方式(根据某个类的相对路径指定)
configuration.setClassForTemplateLoading(this.getClass(), "/static/template/");
// 输出文档路径及名称
File outFile = new File("D:/船舶载运集装箱开箱检查通知书"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".doc");
//以utf-8的编码读取ftl文件 名字要正确,最好不要放在本地,可能会出现找不到。
Template t1 = configuration.getTemplate("unpackCheck.ftl", "utf-8");
// Template t = configuration.getTemplate("a.ftl","utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);
t1.process(param, out);
out.close();
}catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
3、Controller层代码实现
@PostMapping("/exportSimpleWord")
public void exportSimpleWord(@RequestBody Map<String,Object> param) {
dangerCompareService.exportSimpleWord(param);
}