Java 使用 docx4j 创建表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19958476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create table with docx4j
提问by user1335772
I try to create a new table depending on input data and insert it into an docx-document. Following leads to a corrupted output file:
我尝试根据输入数据创建一个新表并将其插入到 docx 文档中。以下导致损坏的输出文件:
private Tbl getSampleTable(WordprocessingMLPackage wPMLpackage) {
ObjectFactory factory = Context.getWmlObjectFactory();
int writableWidthTwips = wPMLpackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
List<Map<String, String>> data = getSampleTableData();
TableDefinition tableDef = getSampleTableDef();
int cols = tableDef.getColumns().size();
int cellWidthTwips = new Double(Math.floor((writableWidthTwips / cols))).intValue();
Tbl table = TblFactory.createTable((data.size() + 1), cols, cellWidthTwips);
Tr headerRow = (Tr) table.getContent().get(0);
int f = 0;
for (Column column : tableDef.getColumns()) {
Tc column = (Tc) headerRow.getContent().get(f);
f++;
Text text = factory.createText();
text.setValue(column.getName());
R run = factory.createR();
run.getContent().add(text);
column.getContent().add(run);
headerRow.getContent().add(column);
}
int i = 1;
for (Map<String, String> entry : data) {
Tr row = (Tr) table.getContent().get(i);
i++;
int p = 0;
for (String key : entry.keySet()) {
Tc column = (Tc) row.getContent().get(p);
p++;
Text tx = factory.createText();
R run = factory.createR();
tx.setValue(entry.get(key));
run.getContent().add(tx);
column.getContent().add(run);
row.getContent().add(column);
}
}
return table;
}
Without inserting the table the docx-document is created how it shall be.
在不插入表格的情况下,docx-document 是如何创建的。
I use the this function by trying to insert this table in an file that I receive as input parameter:
我通过尝试将此表插入到我作为输入参数接收的文件中来使用此函数:
ByteArrayInputStream bis = new ByteArrayInputStream(file);
WordprocessingMLPackage wPMLpackage = null;
wPMLpackage = WordprocessingMLPackage.load(bis);
// Zip it up
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SaveToZipFile saver = new SaveToZipFile(wPMLpackage);
saver.save(baos);
byte[] template = baos.toByteArray();
WordprocessingMLPackage target = WordprocessingMLPackage.load(new ByteArrayInputStream(template));
target.getMainDocumentPart().getContent().clear();
target.getMainDocumentPart().addObject(getSampleTable(target));
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
SaveToZipFile saver2 = new SaveToZipFile(target);
saver2.save(baos2);
return baos2.toByteArray();
Someone has an idea why the generated file can't be interpreted by Microsoft Word? The error message is "The file can't be opened as its contents causes problems". Manipulation of the document works as long as I don't insert this table.
有人知道为什么生成的文件不能被 Microsoft Word 解释吗?错误消息是“无法打开文件,因为其内容导致问题”。只要我不插入这个表,文档的操作就可以工作。
采纳答案by user1335772
Inserting the runs in paragraphs leads to the desired result:
在段落中插入运行会导致所需的结果:
private Tbl getSampleTable(WordprocessingMLPackage wPMLpackage) {
ObjectFactory factory = Context.getWmlObjectFactory();
int writableWidthTwips = wPMLpackage.getDocumentModel().getSections()
.get(0).getPageDimensions()
.getWritableWidthTwips();
List<Map<String, String>> data = getSampleTableData();
TableDefinition tableDef = getSampleTableDef();
int cols = tableDef.getColumns().size();
int cellWidthTwips = new Double(
Math.floor((writableWidthTwips / cols))
).intValue();
Tbl table = TblFactory.createTable((data.size() + 1), cols, cellWidthTwips);
Tr headerRow = (Tr) table.getContent().get(0);
int f = 0;
for (Column column : tableDef.getColumns()) {
Tc column = (Tc) headerRow.getContent().get(f);
P columnPara = (P) column.getContent().get(0);
f++;
Text text = factory.createText();
text.setValue(column.getName());
R run = factory.createR();
run.getContent().add(text);
columnPara.getContent().add(run);
}
int i = 1;
for (Map<String, String> entry : data) {
Tr row = (Tr) table.getContent().get(i);
i++;
int d = 0;
for (String key : entry.keySet()) {
Tc column = (Tc) row.getContent().get(d);
P columnPara = (P) column.getContent().get(0);
d++;
Text tx = factory.createText();
R run = factory.createR();
tx.setValue(entry.get(key));
run.getContent().add(tx);
columnPara.getContent().add(run);
}
}
return table;
}
回答by JasonPlutext
In creating a table (or anything else for that matter), one approach worth bearing in mind is to create what you want in Word, then use one of the docx4j code gen tools to generate corresponding Java code.
在创建表格(或其他任何与此相关的内容)时,值得牢记的一种方法是在 Word 中创建您想要的内容,然后使用其中一种 docx4j 代码生成工具生成相应的 Java 代码。
The code gen tool is available 2 ways:
代码生成工具有两种可用方式:
- online at http://webapp.docx4java.org/OnlineDemo/PartsList.html
- or as a Word AddIn, see http://www.docx4java.org/forums/docx4jhelper-addin-f30/
- 在线http://webapp.docx4java.org/OnlineDemo/PartsList.html
- 或作为 Word 插件,请参阅http://www.docx4java.org/forums/docx4jhelper-addin-f30/
The advantage of the Word AddIn is that you avoid the save-upload cycle.
Word AddIn 的优点是您可以避免保存上传周期。