概要
需求分析
前些时间做一个生成doc文档的需求,doc模板内容中有特殊格式的段落,而且段落的内容格式固定,但是有多个,需要遍历数据,也就是处理数据过程中需要用到循环;
如果是在表格中用传统的填充<域>就能直接搞定,但因为是段落内容的遍历所以此方法不太好使,这里分享一个方法。
我的实现思路
如果填充域不好用,那为何不能干脆直接把内容生成好,放在一个String变量中,然后将这一堆内容直接插入到文档中多好,又快对doc的操作又不多,只需要把内容生成好,这些过程全可以在java代码中实现
故本章博客来讲讲,java使用aspose操作doc文档插入有格式的内容,通过转成html内容填入到doc中
实现流程
① 简化模板
将需求中的doc简化成模板
简化后:
② 生成html
这步过程要用到富文本编辑器,富文本编辑器的用处就是将doc的内容复制粘贴进去后,富文本编辑器会保留其doc原有的格式
然后就可以拿到带有样式的html内容
④ 处理数据
这一步就因人而异,业务不同,处理的数据也不同,此处我的代码仅做参考
将段落中每一行的内容拆分,装到常量中,方便后续使用
public final static String GROUP_NAME_STRING = "<p style=\"line-height:29px\"><span style=\";font-family:仿宋;font-size:19px\"> </span><span style=\";font-family:黑体;font-size:19px\"><span style=\"font-family:黑体\">[groupName]</span></span></p>";
public final static String QUESTION_NAME_STRING = "<p style=\"text-indent:32px;line-height:29px\"><strong><span style=\";font-family:仿宋;font-size:19px\"><span style=\"font-family:仿宋\">问</span><span style=\"font-family:仿宋\">[questionName]</span></span></strong></p>";
public final static String DA_STRING = "<p style=\"text-indent:32px;line-height:29px\"><span style=\";font-family:仿宋;font-size:19px\"><span style=\"font-family:仿宋\">答</span><span style=\"font-family:仿宋\">:</span></span><span style=\"font-family: 仿宋;font-size: 19px\"> </span></p>";
public final static String ANSWER_STRING = "<p style=\"text-indent:32px;line-height:29px\"><span style=\"font-family: 仿宋; font-size: 19px;\">[answer]</span></p><p><br/></p>";
可以看出,只需要将整理好的数据替换其中的[groupName] [questionName] [answer]即可,其他样式不需要修改
StringBuilder builder = new StringBuilder();
int index = 1;
for (Map.Entry<String, List<InterviewQuestion>> e : map.entrySet()) {
// 小组题
String groupName = e.getKey();
List<InterviewQuestion> interviewQuestions = e.getValue();
interviewQuestions.sort(Comparator.comparing(InterviewQuestion::getOrder));
String groupNameStr = AppraiseSummaryConstant.GROUP_NAME_STRING.replace("[groupName]", groupName);
builder.append(groupNameStr);
for (int i = 0; i < interviewQuestions.size(); i++) {
// 具体题
InterviewQuestion interviewQuestion = interviewQuestions.get(i);
String questionNameStr = AppraiseSummaryConstant.QUESTION_NAME_STRING.replace("[questionName]",
StrKit.format("{}", interviewQuestion.getQuestionName()));
builder.append(questionNameStr);
// “答”
builder.append(AppraiseSummaryConstant.DA_STRING);
List<String> answerContentList = interviewQuestion.getAnswerContentList();
// 答案
for (int j = 0; j < answerContentList.size(); j++) {
String answerStr = AppraiseSummaryConstant.ANSWER_STRING.replace("[answer]", StrKit.format(
"({}){}", String.valueOf(j + 1), answerContentList.get(j)));
builder.append(answerStr);
}
}
index++;
}
return builder.toString();
*③ 插入到doc文档中
此处用到了aspose插件中的 insertHtml() 方法,将带有格式的html内容插入到文档中,并解析成doc内容
不可以当做text直接填入内容,否则将不会解析格式,html的代码也会被填入到word中
// Java生成word文档 通过html带入格式填充内容
Document mainDocument = new Document(new ByteArrayInputStream(bytes));
DocumentBuilder builder = new DocumentBuilder(mainDocument);
// 通过书签标记 找到插入的位置
var bookmarkContent = mainDocument.getRange().getBookmarks().get("interviewDataStr");
bookmarkContent.setText("");
builder.moveToBookmark("interviewDataStr");
// interviewDataStr : 这个就是带有格式的html内容字符串
builder.insertHtml(interviewDataStr);
builder.moveToDocumentEnd();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
mainDocument.save(outputStream, SaveFormat.DOC);
bytes = outputStream.toByteArray();
完成!
小结
当一些常用的生成doc内容方法不好实现时,这种通过转成html代码,带着格式插入到文档中,也不为是一种快捷的方法