安装openoffic启动服务请参考:
java 调用OpenOffice将word格式文件转换为pdf格式 - warrior1234 - 博客园
maven包:
<!-- https://mvnrepository.com/artifact/freemarker/freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.jacob/jacob -->
<dependency>
<groupId>com.jacob</groupId>
<artifactId>jacob</artifactId>
<version>1.18</version>
<scope>system</scope>
<systemPath>E:/jacob-1.18/jacob-1.18/jacob.jar</systemPath>
</dependency>
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
直接干活:
package com.nwpusct.csal.common.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import sun.misc.BASE64Encoder;
import java.io.*;
/**
* freemarker + word模板 导出word
*
* @author bobo
* @date 2019/4/14 17:41
*/
public class FreemarkeExportrWordUtil {
/** 默FreeMarker配置实例 */
private static final Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
/** 默认采用UTF-8编码 */
private static final String ENCODING = "UTF-8";
/** buffer */
private static final int BUFFER_SIZE = 1024;
/**
* 从指定freemarker模板所在文件夹
*
* “/” 对应 classpath
* “/templates/” 对应 classpath下的templates/
*/
private static final String DEFAULT_POSITION = "/";
static {
configuration.setDefaultEncoding(ENCODING);
}
/**
* 导出excel
*
* @param templateFileName
* 模板文件名(含后缀,如:abc.ftl)
* @param resultFileAllPathName
* 结果文件全路径文件名 (如: C:/Users/result.doc 再如: C:/Users/result.docx)
* @param dataObject
* 与模板中的占位符 对应的 数据信息(一般为:一个专门创建的对象, 或者是Map)
* @return 生成的word文件
* @throws IOException
* @throws TemplateException
* @date 2019/4/16 10:52
*/
public static File doExport(String templateFileName, String resultFileAllPathName, Object dataObject)
throws IOException, TemplateException {
return doExport(templateFileName, DEFAULT_POSITION, resultFileAllPathName, dataObject);
}
/**
* 导出excel
*
* @param templateFileName
* 模板文件名(含后缀,如:abc.ftl)
* @param templateFileDir
* 模板文件所在位置名(如: "/" 代表 classpath)
* @param resultFileAllPathName
* 结果文件全路径文件名 (如: C:/Users/result.doc 再如: C:/Users/result.docx)
* @param dataObject
* 与模板中的占位符 对应的 数据信息(一般为:一个专门创建的对象, 或者是Map)
* @return 生成的word文件
* @throws IOException
* @throws TemplateException
* @date 2019/4/16 10:52
*/
public static File doExport(String templateFileName, String templateFileDir,
String resultFileAllPathName, Object dataObject)
throws IOException, TemplateException {
// 指定模板文件所在 位置
configuration.setClassForTemplateLoading(FreemarkeExportrWordUtil.class, templateFileDir);
// 根据模板文件、编码;获取Template实例
Template template = configuration.getTemplate(templateFileName, ENCODING);
File resultFile = new File(resultFileAllPathName);
// 判断要生成的word文件所在目录是否存在,不存在则创建
if (!resultFile.getParentFile().exists()) {
boolean result = resultFile.getParentFile().mkdirs();
}
// 写出文件
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(resultFile),
"UTF-8");
Writer writer = new BufferedWriter(osw, BUFFER_SIZE)) {
template.process(dataObject, writer);
}
return resultFile;
}
/**
* 获取图片对应的base64码
*
* @param imgFile
* 图片
* @return 图片对应的base64码
* @throws IOException
* @date 2019/4/16 17:05
*/
public static String getImageBase64String(File imgFile) throws IOException {
InputStream inputStream = new FileInputStream(imgFile);
byte[] data = new byte[inputStream.available()];
int totalNumberBytes = inputStream.read(data);
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
package com.nwpusct.csal.common.exportUtil;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.List;
/**导出工具类
* pdf,图片
* @Author hebo
* @Date 9:55 2019/4/30
*/
public class exportUtil {
public static String realWord(String source, String target) {
ActiveXComponent app = null;
Dispatch doc = null;
try {
app = new ActiveXComponent("Word.Application");
app.setProperty("Visible", false);
Dispatch documents = app.getProperty("Documents").toDispatch();
// 打开FreeMarker生成的Word文档
doc = Dispatch.call(documents, "Open", source, false, true).toDispatch();
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
// 另存为新的Word文档
Dispatch.call(doc, "SaveAs", target, 12);
Dispatch.call(doc, "Close", false);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (app != null) {
app.invoke("Quit", new Variant[]{});
}
ComThread.Release();
String command = "taskkill /f /im WINWORD.EXE";
try {
Runtime.getRuntime().exec(command);
} catch (Exception e) {
e.printStackTrace();
}
}
return target;
}
public static String wordTurnPdf(String doc, String pdf) {
File outFile = null;
File inputFile = new File(doc);
outFile = new File(pdf);
outFile.getParentFile().mkdirs();
OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
try {
connection.connect();
} catch (ConnectException e) {
e.printStackTrace();
}
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(inputFile, outFile);
connection.disconnect();
return pdf;
}
public static String pdf2multiImage(String pdfFile, String outpath) {
try {
InputStream is = new FileInputStream(pdfFile);
PDDocument pdf = PDDocument.load(is);
int actSize = pdf.getNumberOfPages();
List<BufferedImage> piclist = new ArrayList<BufferedImage>();
for (int i = 0; i < actSize; i++) {
BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i,130, ImageType.RGB);
piclist.add(image);
}
yPic(piclist, outpath);
is.close();
return outpath;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void pdf2multiImage(InputStream is, String outpath) {
try {
PDDocument pdf = PDDocument.load(is);
int actSize = pdf.getNumberOfPages();
List<BufferedImage> piclist = new ArrayList<BufferedImage>();
for (int i = 0; i < actSize; i++) {
BufferedImage image = new PDFRenderer(pdf).renderImageWithDPI(i,130,ImageType.RGB);
piclist.add(image);
}
yPic(piclist, outpath);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 将宽度相同的图片,竖向追加在一起 ##注意:宽度必须相同
* @param piclist
* 文件流数组
* @param outPath
* 输出路径
*/
public static void yPic(List<BufferedImage> piclist, String outPath) {// 纵向处理图片
if (piclist == null || piclist.size() <= 0) {
System.out.println("图片数组为空!");
return;
}
try {
int height = 0, // 总高度
width = 0, // 总宽度
_height = 0, // 临时的高度 , 或保存偏移高度
__height = 0, // 临时的高度,主要保存每个高度
picNum = piclist.size();// 图片的数量
int[] heightArray = new int[picNum]; // 保存每个文件的高度
BufferedImage buffer = null; // 保存图片流
List<int[]> imgRGB = new ArrayList<int[]>(); // 保存所有的图片的RGB
int[] _imgRGB; // 保存一张图片中的RGB数据
for (int i = 0; i < picNum; i++) {
buffer = piclist.get(i);
heightArray[i] = _height = buffer.getHeight();// 图片高度
if (i == 0) {
width = buffer.getWidth();// 图片宽度
}
height += _height; // 获取总高度
_imgRGB = new int[width * _height];// 从图片中读取RGB
_imgRGB = buffer.getRGB(0, 0, width, _height, _imgRGB, 0, width);
imgRGB.add(_imgRGB);
}
_height = 0; // 设置偏移高度为0
// 生成新图片
BufferedImage imageResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < picNum; i++) {
__height = heightArray[i];
if (i != 0) _height += __height; // 计算偏移高度
imageResult.setRGB(0, _height, width, __height, imgRGB.get(i), 0, width); // 写入流中
}
File outFile = new File(outPath);
ImageIO.write(imageResult, "jpg", outFile);// 写图片
} catch (Exception e) {
e.printStackTrace();
}
}
}
控制层:
package com.nwpusct.csal.controller.manage;
import com.nwpusct.csal.common.exportUtil.exportUtil;
import com.nwpusct.csal.common.util.FreemarkeExportrWordUtil;
import com.nwpusct.csal.common.util.RestResult;
import com.nwpusct.csal.common.util.RestResultUtil;
import com.nwpusct.csal.mapper.NdeReportInfoMapper;
import com.nwpusct.csal.model.NdeReportInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
/**
* @Author hebo
* @Date 14:09 2019/3/27
*/
@Api(tags = {"导出文件"})
@CrossOrigin
@RestController
@RequestMapping(value = "/export")
public class NdeExportFile {
@Autowired
private NdeReportInfoMapper ndeReportInfoMapper;
@Value("${image.http-path}")
private String httpPath;
@Value("${export.path-pdf}")
private String pathPdf;
@Value("${export.path-word}")
private String pathWord;
@Value("${export.path-jpg}")
private String pathJpg;
@ApiOperation(value = "word文档导出")
@RequestMapping(value = "getExportWord", method = RequestMethod.GET)
public RestResult<String> getExportWord(@RequestParam(value = "infoId") String infoId) {
try {
NdeReportInfo ndeReportInfo = ndeReportInfoMapper.selectById(infoId);
String reportParmeter = ndeReportInfo.getReportParmeter();
// 模板文件名
String templateFileName = "templates/4-18.ftl";
// 要生成的文件 全路径文件名
String fileName =
pathWord + new SimpleDateFormat("yyyyMMDDHHmmss").format(new Date()) + ".doc";
JSONArray jsonArray = new JSONArray(reportParmeter);
Map<String, Object> datas = new HashMap<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONArray tables = jsonObject.getJSONArray("tables");
List<Map<String, Object>> list = new ArrayList<>();
datas.put("table" + i, list);
for (int j = 0; j < tables.length(); j++) {
JSONObject jsonObject1 = tables.getJSONObject(j);
JSONObject tbs = jsonObject1.getJSONObject("tbody");
JSONArray trsTbs = tbs.getJSONArray("trs");
for (int k = 0; k < trsTbs.length(); k++) {
JSONObject jsonTrs = trsTbs.getJSONObject(k);
JSONArray tds = jsonTrs.getJSONArray("tds");
Map<String, Object> tempMap = new HashMap<>();
Integer string = jsonTrs.getInt("loop");
if (string == 1) {
int line = 0;
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
String type = jsonTds.getString("type");
if (type.equals("input")) {
String value = jsonTds.getString("value");
tempMap.put("Td" + line, value);
line++;
} else if (type.equals("label")) {
String value1 = jsonTds.getString("label_chn");
String value2 = jsonTds.getString("label_en");
tempMap.put("Td" + line, value1);
line++;
tempMap.put("Td" + line, value2);
line++;
}
}
list.add(tempMap);
//特殊表格数据说明
//if (tempMap.size() == 14) {
// list.add(tempMap);
//tempMap = new HashMap<>();
//line=0;
//}
}
if (string == 0) {
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
if (jsonTds.length() != 0) {
String type = jsonTds.getString("type");
if (type.equals("input")) {
if (jsonTds.getString("filed").equals("examinationTo")) {
String value = jsonTds.getString("value");
datas.put("examinationTo", value);
}
if (jsonTds.getString("filed").equals("commissionNo")) {
String value = jsonTds.getString("value");
datas.put("commissionNo", value);
}
if (jsonTds.getString("filed").equals("reportNo")) {
String value = jsonTds.getString("value");
datas.put("reportNo", value);
}
}
}
}
}
}
}
}
if (ndeReportInfo.getSketch() != null && ndeReportInfo.getSketch() != "") {
try {
File imageFile = new File(ndeReportInfo.getSketch());
datas.put("myImage",
FreemarkeExportrWordUtil.getImageBase64String(imageFile));
} catch (
IOException e) {
e.printStackTrace();
}
}
FreemarkeExportrWordUtil.doExport(templateFileName, fileName, datas);
String doc = exportUtil.realWord(fileName, pathWord + ndeReportInfo.getInfoName() + ".doc");
File fileDelete = new File(fileName);
fileDelete.delete();
return RestResultUtil.genSuccessResult(httpPath + doc.replaceAll("E:", ""));
} catch (
Exception e) {
e.printStackTrace();
}
return RestResultUtil.failed("导出失败");
}
@ApiOperation(value = "pdf文档导出")
@RequestMapping(value = "getExportPdf", method = RequestMethod.GET)
public RestResult<String> getExportPdf(@RequestParam(value = "infoId") String infoId) {
try {
NdeReportInfo ndeReportInfo = ndeReportInfoMapper.selectById(infoId);
String reportParmeter = ndeReportInfo.getReportParmeter();
// 模板文件名
String templateFileName = "templates/4-18.ftl";
// 要生成的文件 全路径文件名E:\learn\SecurityTest\src\main\resources\importWord
File file1 = new File(pathWord);
if (!file1.exists()) {
file1.mkdir();
}
String fileName =
pathWord + new SimpleDateFormat("yyyyMMDDHHmmss").format(new Date()) + ".doc";
JSONArray jsonArray = new JSONArray(reportParmeter);
Map<String, Object> datas = new HashMap<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONArray tables = jsonObject.getJSONArray("tables");
List<Map<String, Object>> list = new ArrayList<>();
datas.put("table" + i, list);
for (int j = 0; j < tables.length(); j++) {
JSONObject jsonObject1 = tables.getJSONObject(j);
JSONObject tbs = jsonObject1.getJSONObject("tbody");
JSONArray trsTbs = tbs.getJSONArray("trs");
for (int k = 0; k < trsTbs.length(); k++) {
JSONObject jsonTrs = trsTbs.getJSONObject(k);
JSONArray tds = jsonTrs.getJSONArray("tds");
Map<String, Object> tempMap = new HashMap<>();
Integer string = jsonTrs.getInt("loop");
if (string == 1) {
int line = 0;
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
String type = jsonTds.getString("type");
if (type.equals("input")) {
String value = jsonTds.getString("value");
tempMap.put("Td" + line, value);
line++;
} else if (type.equals("label")) {
String value1 = jsonTds.getString("label_chn");
String value2 = jsonTds.getString("label_en");
tempMap.put("Td" + line, value1);
line++;
tempMap.put("Td" + line, value2);
line++;
}
}
list.add(tempMap);
}
if (string == 0) {
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
if (jsonTds.length() != 0) {
String type = jsonTds.getString("type");
if (type.equals("input")) {
if (jsonTds.getString("filed").equals("examinationTo")) {
String value = jsonTds.getString("value");
datas.put("examinationTo", value);
}
if (jsonTds.getString("filed").equals("commissionNo")) {
String value = jsonTds.getString("value");
datas.put("commissionNo", value);
}
if (jsonTds.getString("filed").equals("reportNo")) {
String value = jsonTds.getString("value");
datas.put("reportNo", value);
}
}
}
}
}
}
}
}
if (ndeReportInfo.getSketch() != null && ndeReportInfo.getSketch() != "") {
try {
File imageFile = new File(ndeReportInfo.getSketch());
datas.put("myImage",
FreemarkeExportrWordUtil.getImageBase64String(imageFile));
} catch (
IOException e) {
e.printStackTrace();
}
}
FreemarkeExportrWordUtil.doExport(templateFileName, fileName, datas);
try {
File file2 = new File(pathPdf);
if (!file2.exists()) {
file2.mkdir();
}
String doc = exportUtil.realWord(fileName,
pathWord + ndeReportInfo.getInfoName() + ".doc");
String pdf = exportUtil.wordTurnPdf(doc, pathPdf + ndeReportInfo.getInfoName() +
".pdf");
File fileDelete = new File(fileName);
fileDelete.delete();
File fileDoc = new File(doc);
fileDoc.delete();
fileDelete.delete();
return RestResultUtil.genSuccessResult(httpPath + pdf.replaceAll("E:", ""));
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return RestResultUtil.failed("导出失败");
}
@ApiOperation(value = "图片导出")
@RequestMapping(value = "getExportJPG", method = RequestMethod.GET)
public RestResult<String> getExportJPG(@RequestParam(value = "infoId") String infoId) {
try {
NdeReportInfo ndeReportInfo = ndeReportInfoMapper.selectById(infoId);
String reportParmeter = ndeReportInfo.getReportParmeter();
// 模板文件名
String templateFileName = "templates/4-18.ftl";
// 要生成的文件 全路径文件名E:\learn\SecurityTest\src\main\resources\importWord
File file1 = new File(pathWord);
if (!file1.exists()) {
file1.mkdir();
}
String fileName =
pathWord + new SimpleDateFormat("yyyyMMDDHHmmss").format(new Date()) + ".doc";
JSONArray jsonArray = new JSONArray(reportParmeter);
Map<String, Object> datas = new HashMap<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONArray tables = jsonObject.getJSONArray("tables");
List<Map<String, Object>> list = new ArrayList<>();
datas.put("table" + i, list);
for (int j = 0; j < tables.length(); j++) {
JSONObject jsonObject1 = tables.getJSONObject(j);
JSONObject tbs = jsonObject1.getJSONObject("tbody");
JSONArray trsTbs = tbs.getJSONArray("trs");
for (int k = 0; k < trsTbs.length(); k++) {
JSONObject jsonTrs = trsTbs.getJSONObject(k);
JSONArray tds = jsonTrs.getJSONArray("tds");
Map<String, Object> tempMap = new HashMap<>();
Integer string = jsonTrs.getInt("loop");
if (string == 1) {
int line = 0;
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
String type = jsonTds.getString("type");
if (type.equals("input")) {
String value = jsonTds.getString("value");
tempMap.put("Td" + line, value);
line++;
} else if (type.equals("label")) {
String value1 = jsonTds.getString("label_chn");
String value2 = jsonTds.getString("label_en");
tempMap.put("Td" + line, value1);
line++;
tempMap.put("Td" + line, value2);
line++;
}
}
list.add(tempMap);
}
if (string == 0) {
for (int l = 0; l < tds.length(); l++) {
JSONObject jsonTds = tds.getJSONObject(l);
if (jsonTds.length() != 0) {
String type = jsonTds.getString("type");
if (type.equals("input")) {
if (jsonTds.getString("filed").equals("examinationTo")) {
String value = jsonTds.getString("value");
datas.put("examinationTo", value);
}
if (jsonTds.getString("filed").equals("commissionNo")) {
String value = jsonTds.getString("value");
datas.put("commissionNo", value);
}
if (jsonTds.getString("filed").equals("reportNo")) {
String value = jsonTds.getString("value");
datas.put("reportNo", value);
}
}
}
}
}
}
}
}
if (ndeReportInfo.getSketch() != null && ndeReportInfo.getSketch() != "") {
try {
File imageFile = new File(ndeReportInfo.getSketch());
datas.put("myImage",
FreemarkeExportrWordUtil.getImageBase64String(imageFile));
} catch (
IOException e) {
e.printStackTrace();
}
}
FreemarkeExportrWordUtil.doExport(templateFileName, fileName, datas);
try {
File file2 = new File(pathPdf);
if (!file2.exists()) {
file2.mkdir();
}
File file3 = new File(pathJpg);
if (!file3.exists()) {
file3.mkdir();
}
String doc = exportUtil.realWord(fileName,
pathWord + ndeReportInfo.getInfoName() + ".doc");
String pdf = exportUtil.wordTurnPdf(doc, pathPdf + ndeReportInfo.getInfoName() +
".pdf");
String jpg = exportUtil.pdf2multiImage(pdf, pathJpg + ndeReportInfo.getInfoName() +
".jpg");
File fileDoc = new File(fileName);
File Doc = new File(doc);
File filePdf = new File(pdf);
Doc.delete();
fileDoc.delete();
filePdf.delete();
return RestResultUtil.genSuccessResult(httpPath + jpg.replaceAll("E:", ""));
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return RestResultUtil.failed("导出失败");
}
}
初学者,大神莫怪。互相学习
特殊情况说明部分
模板下载:
我用阿里云盘分享了「word模板导出」,你可以不限速下载🚀
复制这段内容打开「阿里云盘」App 即可获取
链接:https://www.aliyundrive.com/s/ZpknUknphtY
换行符修改: