java-springboot中使⽤freemarker模板⽣成并doc与pdf⽂件接⼝⼏乎已经兼容了所有主流的浏览器。
这个功能还是我接⼿的别⼈写的未成品基础上写的……顺便吐槽下ftl模板⽂件是真的⿇烦!
使⽤freemarker模板⽣成doc与pdf⽂件。⼀般使⽤freemarker模板⽣成doc与pdf⽂件的功能是因为系统中有需要固定⽣成的⽂档格式需求,本篇基本能解决这类需求。⼤家可以通过这篇博⽂进⾏学习和参考。
模板的上传功能就不写了,因为⼤家的⽂件存储⽅式和位置都不同,只写如何⽣成doc和pdf的功能。
以下是代码内容:
1、controller:
/**
* 下载
*
* @param
* @param id 是模板的ID
* @param snumber 是要定义的⽂件名称
* @param type 判断是下载什么模板,这⾥⾃定义
* @param downloadtype 下载的⽂件类型
* @throws IOException
* @return
* 具体的传参请根据需求修改
*/
@RequestMapping(value = "download")
@ResponseBody
public JSONObject exportToWord(HttpServletResponse response, HttpServletRequest request,
@RequestParam("id") String id,
@RequestParam("snumber") String snumber,
@RequestParam("downloadtype") String downloadtype,
@RequestParam("type") String type) throws Exception {
//map⽤来存放需要插⼊⽂件的内容
Map<String, Object> map = new HashMap<>();
InputStream input = null;
OutputStream outs = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
//这⾥定义实体list的数据对象,根据⾃⼰的需求请灵活使⽤
List<ExportContract> list = new ArrayList<ExportContract>();
JSONObject jsonobj = new JSONObject();
//使⽤临时⽂件
File file = ateTempFile(snumber,".doc");
log.info("临时⽂件所在的本地路径:" + CanonicalPath());
String PDFfileName =null;
try {
if(Integer.parseInt((type)) ==0 ){//判断是下载什么模板
//获取插⼊模板的数据
list = server.findAlldataByOrderId(snumber);
}else if(Integer.parseInt((type)) ==2 ){
/
/获取插⼊模板的数据
list = server.findAlldataByOrder(snumber);
}
if (list == null || list.size() <= 0) {
jsonobj.put("success", false);
jsonobj.put("msg", "获取数据失败!");
return jsonobj;
}
ExportContract ext = (0);
//账户名称
map.put("sname ", Sname());
map.put("sname ", Sname());
//list遍历表格数据,根据freemarker规范定义,表格内的数据需要单独存放
List<Map> prolist = new ArrayList<Map>();
for (int i = 0; i < list.size(); i++) {
Map<String, Object> mapdetail = new HashMap<String, Object>();
ExportContract extdtl = (i);
//数量
mapdetail.put("qty", Qty());
prolist.add(mapdetail);
}
map.put("prolist", prolist);
/
/读取ftl⽂件
Configuration conf = new Configuration(new Version("2.3.0"));
conf.setDefaultEncoding("UTF-8");
//模板⽂件的读取⽅式有三种,请根据使⽤场景⾃⾏查询,这⾥只写本地存放ftl⽂件
conf.setDirectoryForTemplateLoading(new File("/contract_template"));
Template tem=null;
//输出⽂档路径及名称
String downFileName = null;
//utf-8读取模板ftl⽂件
String filename = server.findByUrls(id);
//先获取rul,在截取⽂件名
String name = filename;
//Template tem = Template(name, "utf-8");
try {
tem = Template(name);
} catch (Exception e) {
e.printStackTrace();
}
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"), 10240);            tem.process(map, out);
out.close();
// 设置强制下载不打开
if(downloadtype.equals("PDF")){
//word⽂档转pdf⽂档
PDFfileName = CanonicalPath(), null);
log.info("PDF⽂件临时地址:"+PDFfileName);
if(Integer.parseInt((type)) ==0 ){
downFileName = Sname() + snumber + ".pdf";
}else if(Integer.parseInt((type)) ==2 ){
downFileName = Sname() + snumber + ".pdf";
}
bis = new BufferedInputStream(new FileInputStream(PDFfileName));
}else{
if(Integer.parseInt((type)) ==0 ){
downFileName = Sname() + snumber + ".doc";
}else if(Integer.parseInt((type)) ==2 ){
downFileName = Sname() + snumber + ".doc";
}
bis = new BufferedInputStream(new FileInputStream(file));
}
response.setCharacterEncoding("UTF-8");
response.addHeader("Content-Disposition", "attachment;fileName=" + downFileName);
response.setContentType("application/octet-stream;charset=utf-8");
final String agent = Header("User-Agent");
String attachment = "attachment;fileName=";
filename = downFileName;
outs = OutputStream();
bos = new BufferedOutputStream(outs);
bos = new BufferedOutputStream(outs);
String outputFilename = null;
if (agent.indexOf("Firefox") > 0) {
attachment = "attachment;fileName*=";
outputFilename = "=?UTF-8?B?"
+ (new deBase64(filename
.getBytes("UTF-8")))) + "?=";
} else {
if (agent.indexOf("MSIE") != -1) {
outputFilename = new Bytes("gbk"), "iso8859-1");
} else {
outputFilename = new Bytes("UTF-8"), "iso8859-1");
}
}
response.setHeader("Content-Disposition", attachment + outputFilename);
int bytesRead = 0;
// 输⼊流进⾏先读,然后⽤输出流去写,下⾯⽤的是缓冲输⼊输出流
byte[] buffer = new byte[512];
while ((bytesRead = ad(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
log.info("⽂件下载成功!");
jsonobj.put("success", true);
return jsonobj;
} catch (Exception e) {
e.printStackTrace();
log.info("⽂件下载失败!");
jsonobj.put("success", false);
jsonobj.put("msg", "获取数据失败!");
return jsonobj;
} finally {
if (input != null) input.close();
if (outs != null) outs.close();
if (bos !=null) bos.close();
if (bis !=null) bis.close();
//下载完成删除临时⽂件
boolean flag = false;
boolean flagPDF = false;
flag = AbsoluteFile().delete();//这⾥有点⼩bug,懒得改了,使⽤时遇到请⾃⼰解决
File filePDF = new File(PDFfileName);
flagPDF = AbsoluteFile().delete();
log.info("临时WORD⽂件是否删除成功:" + flag);
log.info("临时PDF⽂件是否删除成功:" + flagPDF);
}
}
2、Xml2Word2Pdf转换⼯具类,这个⼯具类是我⽹上到能很好解决转换问题的。使⽤的aspose.words包。如果部署到Linux服务器,出现乱码,看看是不是字体库没有安装。遇到了不能正确实现的问题请⾃⾏探索。
/**
* @Content: xml->word->pdf (通过freemarker把通过word⽣成的xml模板动态添加数据并⽣成word⽂档,通过aspose.words把word⽂档转为pdf⽂档)
* @Description: aspose.words需付费购买,⽬前使⽤破解版,需要引⼊freemarker的jar和aspose-words-jdk16-15.8.0.jar
*/
public class Xml2Word2Pdf {
private static Configuration configuration = null;
/**
* 初始化配置并设置默认编码UTF-8
*/
*/
static {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
/
**
* @Description: 验证aspose.word组件是否授权:⽆授权的⽂件有⽔印标记
*/
public static boolean getLicense() {
boolean result = false;
try {
String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>            ByteArrayInputStream inputStream = new Bytes());
//InputStream inputStream = ClassLoader().getResourceAsStream("\\l");
com.aspose.words.License license = new com.aspose.words.License();
license.setLicense(inputStream);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 使⽤aspose.word把word⽂档转为pdf⽂档
*
* @param sourceFile word⽂档绝对路径(如:D:/templates/order.doc)
* @param destFile  pdf⽂档绝对路径(如:D:/templates/order.pdf)
*/
public static String word2Pdf(String sourceFile, String destFile) throws Exception {
destFile = StringUtils.isEmpty(destFile) ? place(".doc", ".pdf") : destFile;
// 验证License 若不验证则转化出的pdf⽂档会有⽔印产⽣
if (!getLicense()) {
throw new Exception("⽣成PDF⽂档,验证License失败!");
}
try {
File file = new File(destFile);  //新建⼀个空⽩pdf⽂档
FileOutputStream os = new FileOutputStream(file);
/
/解决Linux中⽂⽀持问题,注意,如果部署到新服务器,需要copy window下的字体到Linux服务器字体⽂件夹中。
String osName = Properties().getProperty("os.name");
if (osName.equals("Linux")) {
spring到底是干啥的
FontSettings.setFontsFolder("/usr/share/fonts" + File.separator, true);
}
Document doc = new Document(sourceFile);//通过sourceFile创建word⽂档对象
doc.save(os, SaveFormat.PDF);
os.close();
} catch (Exception e) {
e.printStackTrace();
throw new Exception("⽣成PDF⽂档失败!");
}
return destFile;
}
}
到此,基本实现了这个功能。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。