使用 Java 在 MS Word 文件中创建表格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/399754/
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
Creating tables in a MS Word file using Java
提问by
I want to create a table in a Microsoft Office Word file using Java. Can anybody tell me how to do it with an example?
我想使用 Java 在 Microsoft Office Word 文件中创建一个表格。谁能告诉我如何用一个例子来做到这一点?
回答by eljenso
Have a look at Apache POI
The POI project is the master project for developing pure Java ports of file formats based on Microsoft's OLE 2 Compound Document Format. OLE 2 Compound Document Format is used by Microsoft Office Documents, as well as by programs using MFC property sets to serialize their document objects.
POI 项目是开发基于 Microsoft OLE 2 复合文档格式的文件格式的纯 Java 端口的主项目。Microsoft Office 文档以及使用 MFC 属性集序列化其文档对象的程序都使用 OLE 2 复合文档格式。
回答by Kezzer
I've never seen it done, and I work in Word a lot. If you really want to programatically do something in a word document then I'd advise using Microsoft's scripting language VBA which is specifically designed for this purpose. In fact, I'm working in it right now.
我从未见过它完成,而且我经常在 Word 中工作。如果您真的想以编程方式在 word 文档中执行某些操作,那么我建议您使用专门为此目的设计的 Microsoft 脚本语言 VBA。事实上,我现在正在从事这项工作。
If you're working under Open Office then they have a very similar set of macro-powered tools for doing the same thing.
如果你在 Open Office 下工作,那么他们有一组非常相似的宏驱动工具来做同样的事情。
回答by Andrej
Office 2003 has an xml format, and the default document format for office 2007 is xml (zipped). So you could just generate xml from java. If you open an existing document it's not too hard too see the xml required.
Office 2003 具有 xml 格式,Office 2007 的默认文档格式为 xml(压缩文件)。所以你可以从java生成xml。如果您打开一个现有文档,那么查看所需的 xml 并不太难。
Alternatively, you could use openoffice's api to generate a document, and save it as a ms-word document.
或者,您可以使用 openoffice 的 api 生成文档,并将其保存为 ms-word 文档。
回答by lakshmi
This snippet can be used to create a table dynamically in MS Word document.
此代码段可用于在 MS Word 文档中动态创建表格。
WPFDocument document = new XWPFDocument();
XWPFTable tableTwo = document.createTable();
XWPFTableRow tableTwoRowOne = tableTwo.getRow(0);
tableTwoRowOne.getCell(0).setText(Knode1);
tableTwoRowOne.createCell().setText(tags.get("node1").toString());
for (int i = 1; i < nodeList.length; i++) {
String node = "node";
String nodeVal = "";
XWPFTableRow tr = null;
node = node + (i + 1);
nodeVal = tags.get(node).toString();
if (tr == null) {
tr = tableTwo.createRow();
tr.getCell(0).setText(nodeList[i]);
tr.getCell(1).setText(tags.get(node).toString());
}
}
回答by Mitja Gustin
Using my little zip utility, you can create docx with ease, if you know what you're doing. Word's DOCX file format is simply zip (folders with xml files). By using java zip utilities, you can modify existing docx, just the content part.
使用我的小 zip 实用程序,您可以轻松创建 docx,如果您知道自己在做什么。Word 的 DOCX 文件格式只是 zip(带有 xml 文件的文件夹)。通过使用 java zip 实用程序,您可以修改现有的 docx,仅修改内容部分。
For the following sample to work, simply open Word, enter few lines, save document. Then with zip program, remove file word/document.xml (this is file where main content of the Word document is residing) from the zip. Now you have the template prepared. Save modified zip.
为了让下面的示例工作,只需打开 Word,输入几行,保存文档。然后使用 zip 程序,从 zip 中删除文件 word/document.xml(这是 Word 文档的主要内容所在的文件)。现在您已准备好模板。保存修改后的 zip。
Here is what creation of new Word file looks:
这是创建新 Word 文件的样子:
/* docx file head */
final String DOCUMENT_XML_HEAD =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>" +
"<w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:w10=\"urn:schemas-microsoft-com:office:word\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" xmlns:w15=\"http://schemas.microsoft.com/office/word/2012/wordml\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" mc:Ignorable=\"w14 w15 wp14\">" +
"<w:body>";
/* docx file foot */
final String DOCUMENT_XML_FOOT =
"</w:body>" +
"</w:document>";
final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("c:\TEMP\test.docx"));
final String fullDocumentXmlContent = DOCUMENT_XML_HEAD + "<w:p><w:r><w:t>Hey MS Word, hello from java.</w:t></w:r></w:p>" + DOCUMENT_XML_FOOT;
final si.gustinmi.DocxZipCreator creator = new si.gustinmi.DocxZipCreator();
// create new docx file
creator.createDocxFromExistingDocx(zos, "c:\TEMP\existingDocx.docx", fullDocumentXmlContent);
These are zip utilities:
这些是 zip 实用程序:
package si.gustinmi;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* Creates new docx from existing one.
* @author gustinmi [at] gmail [dot] com
*/
public class DocxZipCreator {
public static final Logger log = Logger.getLogger(DocxZipCreator.class.getCanonicalName());
private static final int BUFFER_SIZE = 4096;
/** OnTheFly zip creator. Traverses through existing docx zip and creates new one simultaneousl.
* On the end, custom document.xml is inserted inside
* @param zipFilePath location of existing docx template (without word/document.xml)
* @param documentXmlContent content of the word/document.xml
* @throws IOException
*/
public void createDocxFromExistingDocx(ZipOutputStream zos, String zipFilePath, String documentXmlContent) throws IOException {
final FileInputStream fis = new FileInputStream(zipFilePath);
final ZipInputStream zipIn = new ZipInputStream(fis);
try{
log.info("Starting to create new docx zip");
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) { // iterates over entries in the zip file
copyEntryfromZipToZip(zipIn, zos, entry.getName());
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
// add document.xml to existing zip
addZipEntry(documentXmlContent, zos, "word/document.xml");
}finally{
zipIn.close();
zos.close();
log.info("End of docx creation");
}
}
/** Copies sin gle entry from zip to zip */
public void copyEntryfromZipToZip(ZipInputStream is, ZipOutputStream zos, String entryName)
{
final byte [] data = new byte[BUFFER_SIZE];
int len;
int lenTotal = 0;
try {
final ZipEntry entry = new ZipEntry(entryName);
zos.putNextEntry(entry);
final CRC32 crc32 = new CRC32();
while ((len = is.read(data)) > -1){
zos.write(data, 0, len);
crc32.update(data, 0, len);
lenTotal += len;
}
entry.setSize(lenTotal);
entry.setTime(System.currentTimeMillis());
entry.setCrc(crc32.getValue());
}
catch (IOException ioe){
ioe.printStackTrace();
}
finally{
try { zos.closeEntry();} catch (IOException e) {}
}
}
/** Create new zip entry with content
* @param content content of a new zip entry
* @param zos
* @param entryName name (npr: word/document.xml)
*/
public void addZipEntry(String content, ZipOutputStream zos, String entryName)
{
final byte [] data = new byte[BUFFER_SIZE];
int len;
int lenTotal = 0;
try {
final InputStream is = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
final ZipEntry entry = new ZipEntry(entryName);
zos.putNextEntry(entry);
final CRC32 crc32 = new CRC32();
while ((len = is.read(data)) > -1){
zos.write(data, 0, len);
crc32.update(data, 0, len);
lenTotal += len;
}
entry.setSize(lenTotal);
entry.setTime(System.currentTimeMillis());
entry.setCrc(crc32.getValue());
}
catch (IOException ioe){
ioe.printStackTrace();
}
finally{
try { zos.closeEntry();} catch (IOException e) {}
}
}
}
回答by Simon
Our feature set is to hit a button in our web app and get the page you are looking at back as a Word document. We use the docx schema for description of documents and have a bunch of Java code on the server side which does the document creation and response back to our web client. The formatting itself is done with some compiled xsl-t's from within Java to translate from our own XML persistence tier.
我们的功能集是在我们的 Web 应用程序中点击一个按钮,然后将您正在查看的页面作为 Word 文档获取。我们使用 docx 模式来描述文档,并在服务器端有一堆 Java 代码,用于创建文档并将响应返回给我们的 Web 客户端。格式化本身是用一些编译的 xsl-t 从 Java 内部完成的,以从我们自己的 XML 持久层转换。
The docx schema is pretty hard to understand. The way we made most progress was to create template docx's in Word with exactly the formatting that we needed but with bogus content. We then fooled around with them until we understood exactly what was going on. There is a huge amount in the docx that you don't really need to worry about. When reading / translating the docx Word is pretty tolerant to a partially complete formatting schema. In fact we chose to strip out pretty much all the formatting because it also means that the user's default formatting takes precedence, which they seem to prefer. It also makes the xsl process faster and the resulting document smaller.
docx 模式很难理解。我们取得最大进展的方法是在 Word 中创建模板 docx,其格式与我们需要的完全相同,但内容是虚假的。然后我们与他们混在一起,直到我们确切地了解发生了什么。docx 中有大量内容是您无需担心的。在阅读/翻译 docx 时,Word 对部分完整的格式模式非常宽容。事实上,我们选择去掉几乎所有的格式,因为这也意味着用户的默认格式优先,他们似乎更喜欢。它还使 xsl 过程更快,生成的文档更小。
回答by dexter
Office Writerwould be a better tool to use than POI for your requirement.
对于您的要求,Office Writer将是比 POI 更好的工具。
If all you want is a simple table without too much of formatting, I would use this simple trick. Use Java to generate the table as HTML using plain old table,tr,td tags and copy the rendered HTML table into the word document ;)
如果你想要的只是一个没有太多格式的简单表格,我会使用这个简单的技巧。使用 Java 使用普通的旧表格、tr、td 标签将表格生成为 HTML,并将呈现的 HTML 表格复制到 Word 文档中;)
回答by JasonPlutext
I manage the docx4j project
我管理 docx4j 项目
docx4j contains a class TblFactory, which creates regular tables (ie no row or column spans), with the default settings which Word 2007 would create, and with the dimensions specified by the user.
docx4j 包含一个类TblFactory,它使用 Word 2007 将创建的默认设置以及用户指定的尺寸创建常规表格(即没有行或列跨度)。
If you want a more complex table, the easiest approach is to create it in Word, then copy the resulting XML into a String in your IDE, where you can use docx4j's XmlUtils.unmarshalString to create a Tbl object from it.
如果您想要更复杂的表格,最简单的方法是在 Word 中创建它,然后将生成的 XML 复制到您的 IDE 中的 String 中,您可以在其中使用 docx4j 的 XmlUtils.unmarshalString 从中创建一个 Tbl 对象。
回答by Cheeso
Click here for a Working example with source code. This example generates MS-Word docs from Java, based on a template concept.

