【问题标题】:Document created with Apache POI is different in Microsoft Word than in LibreOffice Writer使用 Apache POI 创建的文档在 Microsoft Word 中与在 LibreOffice Writer 中不同
【发布时间】:2019-07-18 19:13:00
【问题描述】:

我正在尝试使用 Apache POI 创建 docx 文档。但是,当我在 Microsoft Word 中打开创建的文档时,结果与我使用 LibreOffice Writer 打开时的结果不同。我在使用表和交叉引用时遇到过这种行为。

我想知道是否需要进行任何配置以将输出格式保存为 Microsoft Word 格式。

例如,下面的代码创建了一个包含 2 行 2 列表格的 docx 文档:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

public class DocWithTable {

    public static final int NUM_ROWS = 2;
    public static final int NUM_COLS = 2;

    public static void main(String[] args) throws IOException {
        XWPFDocument document = new XWPFDocument();

        XWPFTable table = document.createTable();
        XWPFTableRow firstRow = table.getRow(0);
        for (int c = 1; c < NUM_COLS; c++) {
            firstRow.addNewTableCell().getCTTc().addNewTcPr();
        }
        for (int r = 1; r < NUM_ROWS; r++) {
            table.createRow();
        }

        FileOutputStream out = new FileOutputStream(new File("file.docx"));
        document.write(out);
        out.close();
        document.close();
    }

}

当我用 Microsoft Word 打开创建文档时,我得到以下结果:

当我用 LibreOffice Writer 打开它时,我得到以下结果:

此外,在 LibreOffice 中保存文档后,它会在 Microsoft Word 中按预期打开。

【问题讨论】:

  • 什么版本的 Apache POI?如果不是最新的,升级时会发生什么?
  • @Gagravarr 由于某些项目限制,我正在使用 apache poi 3.17。较新版本的行为将相同。接受的包含解决 apache poi 4.1.0 中问题的信息。我为以前的版本添加了一个编辑。
  • @Eduardo:这不应该是我回答的编辑,而是您自己的回答。我的回答使用最新的稳定版本。对于apache poi,应始终使用最新的稳定版本。其他代码很快就会过时。而且没有理由不使用最新的稳定版本,是吗?
  • @AxelRichter 根据 Apache POI 页面:“POI 自 4.0.1 版起需要 Java 8 或更高版本”。不幸的是,我必须使用的 JVM 不支持最新的稳定版本。
  • 使用旧的过时 JVM 的原因是什么?我的意思是,我们现在是 Java 12。早于 Java 8 的 JVM 很古老。

标签: java ms-word apache-poi


【解决方案1】:

您的表格单元格都是空的。为此,行为确实不同。如果没有明确设置宽度,Microsoft Word 中的所有表格单元格的宽度都与内容需要的一样宽,LibreOffice Writer 中的表格宽度为可用页面宽度的 100%。

使用apache poi 4.1.0,您可以使用XWPFTable.setWidth 将表格宽度设置为100%,以使行为相等。

在您的代码中:

...
XWPFTable table = document.createTable();

table.setWidth("100%");
...

【讨论】:

    【解决方案2】:

    对于没有XWPFTable.setWidth方法的apache poi版本,可以使用如下代码:

    import java.math.BigInteger;
    
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
    
        ...
        XWPFTable table = document.createTable();
        CTTblWidth ctTblWidth = table.getCTTbl().getTblPr().getTblW();
        ctTblWidth.setType(STTblWidth.PCT);
        ctTblWidth.setW(BigInteger.valueOf(50 * 100)); // 50 times the desired percentage
        ...
    

    【讨论】:

    • @AxelRichter 不错的建议。
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多