一,word模板如下
二,将word模板中的参数对应的值放到map中
/**
* 将word模板中需要的参数值统一放到map中
*
* @param resource
* @param template
* @param job
* @return
*/
public Map<String, String> getWordTemplateParam(ExtractResources resource) {
ExtractJobs extractJob = jobsDao.findById(job.getId()).get();
String statisticsInfo = this.formatStatistic(extractJob.getStatisticsInfo());
Map<String, String> params = new HashMap<String, String>();
params.put("data", statisticsInfo);
params.put("DataReceivingUnit", resource.getOrganization());
params.put("SubjectOrProject", resource.getTopic());
return params;
}
/**
* 需要根据\n换行的参数值
* @param statisticsInfo
* @return
*/
public String formatStatistic(String statisticsInfo) {
String result = "";
String bcmStr = "";
String subDocTypeStr = "";
Map<String, Integer> map = (Map) JSON.parse(statisticsInfo);
Set<Entry<String, Integer>> entrySet = map.entrySet();
for (Entry<String, Integer> entry : entrySet) {
String key = entry.getKey();
Integer value = entry.getValue();
if (Pattern.matches("^[a-zA-Z]+$", key)) {
// 母体类型
String keyStr;
//省略业务代码
keyStr = key;
bcmStr += keyStr + ":" + value + "\n";//这里标识以\n为标识,表名明需要换行
} else {
// 子类型
subDocTypeStr += key + " : " + value + "\n";
}
}
result = result + subDocTypeStr + bcmStr;
return result;
}
三,根据模板生成word文档
/**
* 生成word文档
*/
public void addStatisticWord(ExtractResources resource, ExtractTemplate template, ExtractJobs job) {
OutputStream os = null;
InputStream is = null;
Map<String, String> params = this.getWordTemplateParam(resource,template,job);
try {
// word文档模板路径
String filePath = "D:" + File.separator + "templateWord" + File.separator + "数据模板.docx";
File templateFile = new File(filePath);
if (!templateFile.exists()) {
templateFile.mkdirs();
}
// 输出的word文件名称
String outputName = "NSTL数据交接登记表-" + template.getTemplateName() + "-" + job.getId() + ".docx";
// word输出路径 resourcPath/jobId/success
String outputPath = resource.getFileSavePath() + File.separator + job.getId() + File.separator + "success"+ File.separator + outputName;
is = new FileInputStream(templateFile);
XWPFDocument doc = new XWPFDocument(is);
List<XWPFTable> tables = doc.getTables();// 获取全部表格对象(word模板是一个表格)
for (XWPFTable xwpfTable : tables) {
List<XWPFTableRow> rows = xwpfTable.getRows();// 获取word模板表格每一行
for (XWPFTableRow row : rows) {
List<XWPFTableCell> tableCells = row.getTableCells();//每一行的单元格
for (XWPFTableCell cell : tableCells) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();// 每个单元格里的段落集合
for (XWPFParagraph paragraph : paragraphs) {
String paragraphText = paragraph.getText();
if (this.checkText(paragraphText)) {
//段落文字包含$,代表是参数,需要替换为map中对应的参数值
List<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = this.changeValue(run.toString(), params);//根据参数名到map中获取参数值
paragraph.removeRun(i);//可以理解为删除当前这一个段落
run = paragraph.insertNewRun(i);//然后插入一个新的段落
// 设置字体
run.setFontFamily("黑体");
run.setFontSize(14);
if (runText.contains("\n")) {
//参数值包含\n代表需要换行(也可以设置成\r,只是一个标识,因为我在formatStatistic方法中设置的以\n为标识换行)
String[] text = runText.split("\n");
for (int j = 0; j < text.length; j++) {
run.setText(text[j].trim());//往新的段落里set参数值
run.addBreak();// 换行
}
} else {
run.setText(runText);
}
}
}
}
}
}
}
os = new FileOutputStream(outputPath);
doc.write(os);
} catch (Exception e) {
e.printStackTrace();
} finally {
this.close(os);
this.close(is);
}
}
/**
* 匹配传入信息集合与模板
*
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public String changeValue(String value, Map<String, String> textMap) {
Set<Entry<String, String>> textSets = textMap.entrySet();
for (Entry<String, String> textSet : textSets) {
// 匹配模板与替换值 格式${key}
String key = "${" + textSet.getKey() + "}";
if (value.indexOf(key) != -1) {
value = textSet.getValue();
}
}
// 模板未匹配到区域替换为空
if (checkText(value)) {
value = "";
}
return value;
}
/**
* 判断文本中时候包含$
*
* @param text 文本
* @return 包含返回true,不包含返回false
*/
public boolean checkText(String text) {
boolean check = false;
if (text.indexOf("$") != -1) {
check = true;
}
return check;
}
/**
* 关闭输入流
*
* @param is
*/
private void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭输出流
*
* @param os
*/
private void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}