//添加目錄
public static void generateTOC(XWPFDocument document)
throws InvalidFormatException, FileNotFoundException, IOException {
String findText = "toc";//word模板段落標識(在此標識處生成目錄)
String replaceText = "";
for (XWPFParagraph p : document.getParagraphs()) {
for (XWPFRun r : p.getRuns()) {
int pos = r.getTextPosition();
String text = r.getText(pos);
System.out.println(text);
if (text != null && text.contains(findText)) {
text = text.replace(findText, replaceText);
r.setText(text, 0);
addField(p, "TOC \\o \"1-3\" \\h \\z \\u");
// addField(p, "TOC \\h");
break;
}
}
}
}
private static void addField(XWPFParagraph paragraph, String fieldName) {
CTSimpleField ctSimpleField = paragraph.getCTP().addNewFldSimple();
ctSimpleField.setInstr(fieldName);
ctSimpleField.setDirty(STOnOff.TRUE);
ctSimpleField.addNewR().addNewT().setStringValue("<<fieldName>>");
}
前提
word.docx 模板更改后綴為zip
打開zip 獲取 word 文件夾種document.xml
在document.xml 種填充所需參數${}格式,循環添加<#list items as item></#list>
document.xml 放入項目templates 文件夾中
工具代碼
public class FreeMarkUtils {
private static Logger logger = LoggerFactory.getLogger(FreeMarkUtils.class);
public static Configuration getConfiguration() {
// 創建配置實例
Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
// 設置編碼
configuration.setDefaultEncoding("utf-8");
configuration.setClassForTemplateLoading(FreeMarkUtils.class, "/templates");// 換成自己對應的目錄
return configuration;
}
/**
* 獲取模板字符串輸入流
*
* @param dataMap
* 參數
* @param templateName
* 模板名稱
* @return
*/
public static ByteArrayInputStream getFreemarkerContentInputStream(Map<String, Object> dataMap,
String templateName) {
ByteArrayInputStream in = null;
try {
// 獲取模板
Template template = getConfiguration().getTemplate(templateName);
StringWriter swriter = new StringWriter();
// 生成文件
template.process(dataMap, swriter);
in = new ByteArrayInputStream(swriter.toString().getBytes("utf-8"));// 這里一定要設置utf-8編碼
// 否則導出的word中中文會是亂碼
} catch (Exception e) {
logger.error("", e);
}
return in;
}
public static void createDocx(Map<String, Object> dataMap, OutputStream outputStream, String zipPath) {
ZipOutputStream zipout = null;
try {
/*
* //圖片配置文件模板 ByteArrayInputStream documentXmlRelsInput =
* FreeMarkUtils.getFreemarkerContentInputStream(dataMap,
* documentXmlRels);
*/
// 內容模板
ByteArrayInputStream documentInput = FreeMarkUtils.getFreemarkerContentInputStream(dataMap, "document.xml");
// 最初設計的模板
// File docxFile = new
// File(WordUtils.class.getClassLoader().getResource(template).getPath());
File docxFile = new File(zipPath);// 換成自己的zip路徑
if (!docxFile.exists()) {
docxFile.createNewFile();
}
@SuppressWarnings("resource")
ZipFile zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
zipout = new ZipOutputStream(outputStream);
// 開始覆蓋文檔------------------
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
InputStream is = zipFile.getInputStream(next);
if (next.toString().indexOf("media") < 0) {
zipout.putNextEntry(new ZipEntry(next.getName()));
if ("word/document.xml".equals(next.getName())) {// 如果是word/document.xml由我們輸入
if (documentInput != null) {
while ((len = documentInput.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
documentInput.close();
}
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
is.close();
}
}
}
} catch (Exception e) {
System.out.println("word導出失敗:" + e.getStackTrace());
logger.error("TET", e);
} finally {
if (zipout != null) {
try {
zipout.close();
} catch (IOException e) {
System.out.println("io異常");
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
System.out.println("io異常");
}
}
}
}
// 兩個對象進行追加
public static XWPFDocument mergeWord(XWPFDocument document, XWPFDocument doucDocument2) throws Exception {
XWPFDocument src1Document = document;
XWPFParagraph p = src1Document.createParagraph();
// 設置分頁符
p.setPageBreak(true);
CTBody src1Body = src1Document.getDocument().getBody();
XWPFDocument src2Document = doucDocument2;
CTBody src2Body = src2Document.getDocument().getBody();
// XWPFParagraph p2 = src2Document.createParagraph();
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String appendString = src2Body.xmlText(optionsOuter);
String srcString = src1Body.xmlText();
String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));
String sufix = srcString.substring(srcString.lastIndexOf("<"));
String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart + sufix);
src1Body.set(makeBody);
return src1Document;
}
}
業務代碼
單個word導出
@RequestMapping("/export")
public void export(@RequestBody JSONObject json, HttpServletResponse res) throws Exception {
JSONObject detail = taskService.detail(json);
Map<String, Object> beanParams = new HashMap<>();
beanParams.put("userTestName", detail.getString("user_test_name"));
beanParams.put("postName", detail.getString("post_name"));
beanParams.put("deptName", detail.getString("dept_name"));
beanParams.put("testDate", DateUtils.formatDateDay(detail.getDate("test_date")));
beanParams.put("testUserName", detail.getString("test_user_name"));
beanParams.put("remarks",
StringUtils.isEmpty(detail.getString("remarks_")) ? "" : detail.getString("remarks_"));
beanParams.put("responsibilitys", detail.getJSONArray("responsibility_ids"));
beanParams.put("zf", detail.getInteger("zf"));
// 讀到流中
File outFile = new File(ConfigUtils.getConfigValue("responsibility", "") + ".docx");
try {
FreeMarkUtils.createDocx(beanParams, new FileOutputStream(outFile),
ConfigUtils.getConfigValue("responsibility", "") + ".zip");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
InputStream inStream = new FileInputStream(outFile);// 文件的存放路徑
// 設置輸出的格式
res.setContentType("application/octet-stream; charset=utf-8");
res.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("安全生產責任制.doc"));
res.setCharacterEncoding("utf-8");
// 循環取出流中的數據
byte[] b = new byte[100];
int len;
try {
while ((len = inStream.read(b)) > 0)
res.getOutputStream().write(b, 0, len);
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
合並多個word導出
@RequestMapping("/exports")
public void exports(@RequestBody JSONObject json, HttpServletResponse res) throws Exception {
json.put("enabled_state_id", "1");
List<JSONObject> taskList = taskService.findAllList(json);
if (taskList != null && taskList.size() > 0) {
XWPFDocument docs = null;
for (JSONObject task : taskList) {
json.put("id_", task.getString("id_"));
JSONObject detail = taskService.detail(json);
Map<String, Object> beanParams = new HashMap<>();
beanParams.put("userTestName", detail.getString("user_test_name"));
beanParams.put("postName", detail.getString("post_name"));
beanParams.put("deptName", detail.getString("dept_name"));
beanParams.put("testDate", DateUtils.formatDateDay(detail.getDate("test_date")));
beanParams.put("testUserName", detail.getString("test_user_name"));
beanParams.put("remarks",
StringUtils.isEmpty(detail.getString("remarks_")) ? "" : detail.getString("remarks_"));
beanParams.put("responsibilitys", detail.getJSONArray("responsibility_ids"));
beanParams.put("zf", detail.getInteger("zf"));
//導出指定文件
File outFile = new File("d:/test.docx");
//指定修改word后綴為zip路徑
try {
FreeMarkUtils.createDocx(beanParams, new FileOutputStream(outFile),"d:/test.zip");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (taskList.indexOf(task) == 0) {
docs = new XWPFDocument(new FileInputStream(outFile));
}
if (taskList.indexOf(task) == 1) {
docs = FreeMarkUtils.mergeWord(docs, new XWPFDocument(new FileInputStream(outFile)));
}
if (taskList.indexOf(task) > 1) {
docs = FreeMarkUtils.mergeWord(docs, new XWPFDocument(new FileInputStream(outFile)));
}
}
if (docs != null) {
docs.write(res.getOutputStream());
docs.close();
}
// 設置輸出的格式
res.setContentType("application/octet-stream; charset=utf-8");
res.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("安全生產責任制.doc"));
res.setCharacterEncoding("utf-8");
} else {
}
}
