input文件:
input.docx (10.0 KB)
这是我的原代码:
public static void main(String[] args) throws Exception {
String filename1 = "D:\\input.docx";
String filename2 = "D:\\output.docx";
String bookmarkName = "bookmark";
Document document = new Document(filename1);
DocumentBuilder documentBuilder = new DocumentBuilder(document);
BookmarkCollection bookmarkList = document.getRange().getBookmarks();
List<Bookmark> bookmarks = new ArrayList<>();
for (Bookmark bookmark : bookmarkList) {
bookmarks.add(bookmark);
}
// 获取书签
Bookmark bookmark = bookmarks.stream()
.filter(item -> item.getName().equals(bookmarkName))
.findFirst().orElse(null);
if (bookmark == null) {
log.warn("未扫描到书签", bookmarkName);
return;
}
// 置为空值
bookmark.setText("");
// 文档指针移动到书签位置
documentBuilder.moveToBookmark("bookmark", true, true);
documentBuilder.write(" ");
// 新建表格
documentBuilder.startTable();
documentBuilder.insertCell();
documentBuilder.write("姓名1");
documentBuilder.insertCell();
documentBuilder.write("年龄1");
documentBuilder.endRow();
documentBuilder.insertCell();
documentBuilder.write("姓名2");
documentBuilder.insertCell();
documentBuilder.write("年龄2");
documentBuilder.endRow();
// 结束表格
documentBuilder.endTable();
document.save(filename2);
}
但是我希望插入每个单元格内容时插入内容控件,比如test文件:
test.docx (14.8 KB)
文档结构是这样:
@whitemeen 您可以使用以下代码对表格进行后处理来实现此目的:
for(Row r : t.getRows())
{
for(Cell c : r.getCells())
{
// Create SDT for cell
StructuredDocumentTag tag = new StructuredDocumentTag(document, SdtType.RICH_TEXT, MarkupLevel.CELL);
tag.removeAllChildren();
tag.isShowingPlaceholderText(false);
// Put the tag before the cell and move cell inside the inserted SDT.
c.getParentNode().insertBefore(tag, c);
tag.appendChild(c);
}
}
以下是我这边生成的输出结果:out.docx (13.9 KB)
我们会存在非常复杂的场景,比如以下仅在非加粗的数据位置插入内容控件,甚至更复杂,所以我希望在写入数据的同时插入StructuredDocumentTag内容控件
public static void main(String[] args) throws Exception {
String filename1 = "D:\\input.docx";
String filename2 = "D:\\output.docx";
String bookmarkName = "bookmark";
String[] headers = new String[]{"合同名称", "合同编号"};
List<String[]> tableData = new ArrayList<>();
String[] tableData1 = new String[]{"数据-合同名称1", "数据-合同编号1"};
String[] tableData2 = new String[]{"数据-合同名称2", "数据-合同编号2"};
tableData.add(tableData1);
tableData.add(tableData2);
Document document = new Document(filename1);
DocumentBuilder documentBuilder = new DocumentBuilder(document);
BookmarkCollection bookmarkList = document.getRange().getBookmarks();
List<Bookmark> bookmarks = new ArrayList<>();
for (Bookmark bookmark : bookmarkList) {
bookmarks.add(bookmark);
}
// 获取书签
Bookmark bookmark = bookmarks.stream()
.filter(item -> item.getName().equals(bookmarkName))
.findFirst().orElse(null);
if (bookmark == null) {
log.warn("未扫描到书签", bookmarkName);
return;
}
// 置为空值
bookmark.setText("");
// 文档指针移动到书签位置
documentBuilder.moveToBookmark("bookmark", true, true);
documentBuilder.write(" ");
// 新建表格
documentBuilder.startTable();
documentBuilder.insertCell();
documentBuilder.setBold(true);
documentBuilder.write("项目名称");
documentBuilder.setBold(false);
documentBuilder.insertCell();
documentBuilder.write("数据-xx项目");
documentBuilder.endRow();
documentBuilder.setBold(true);
// 输出表头
for (String header : headers) {
documentBuilder.insertCell();
documentBuilder.write(header);
}
documentBuilder.setBold(false);
documentBuilder.endRow();
// 输出数据
for (String[] rowDate : tableData) {
for (int i = 0; i < rowDate.length; i++) {
documentBuilder.insertCell();
documentBuilder.write(rowDate[i]);
}
// 结束当前行
documentBuilder.endRow();
}
// 结束表格
documentBuilder.endTable();
document.save(filename2);
}
@whitemeen 在这种情况下,我建议收集需要用SDT封装的单元格,然后按照上述方法进行后处理。恐怕没有更简单的方法可以实现您的需求。