XWPF 列超出 docx 文档边界(Ubuntu 16.04 主机)

Posted

技术标签:

【中文标题】XWPF 列超出 docx 文档边界(Ubuntu 16.04 主机)【英文标题】:XWPF Columns out of docx document boundaries (Ubuntu 16.04 host) 【发布时间】:2018-01-11 19:20:50 【问题描述】:

我正在运行带有 LibreOffice v5.1.6.2 的 4.10.0-42-generic Ubuntu 16.04 LTS。 使用 Oxygen Eclipse 4.7.2,通过创建一个 Maven 项目,添加 poi 和 poi-ooxml 3.15 作为依赖项,我正在尝试使用 Java 以 .docx 格式创建一个表。 不用说,我找不到解决方案。我的代码 sn-p 是这样的:

public class Application 

public static void main(String[] args)throws Exception 

   FileOutputStream fos = new FileOutputStream("samplefile.docx");

   XWPFDocument document = new XWPFDocument();

   // New 2x2 table
    XWPFTable tableOne = document.createTable();
    XWPFTableRow tableOneRowOne = tableOne.getRow(0);
    tableOneRowOne.getCell(0).setText("Hello");
    tableOneRowOne.addNewTableCell().setText("World");

    XWPFTableRow tableOneRowTwo = tableOne.createRow();
    tableOneRowTwo.getCell(0).setText("This is");
    tableOneRowTwo.getCell(1).setText("a table");

    // Add a break between the tables
    document.createParagraph().createRun().addBreak();

    // New 3x3 table
    XWPFTable tableTwo = document.createTable();
    XWPFTableRow tableTwoRowOne = tableTwo.getRow(0);
    tableTwoRowOne.getCell(0).setText("col one, row one");
    tableTwoRowOne.addNewTableCell().setText("col two, row one");
    tableTwoRowOne.addNewTableCell().setText("col three, row one");

    XWPFTableRow tableTwoRowTwo = tableTwo.createRow();
    tableTwoRowTwo.getCell(0).setText("col one, row two");
    tableTwoRowTwo.getCell(1).setText("col two, row two");
    tableTwoRowTwo.getCell(2).setText("col three, row two");

    XWPFTableRow tableTwoRowThree = tableTwo.createRow();
    tableTwoRowThree.getCell(0).setText("col one, row three");
    tableTwoRowThree.getCell(1).setText("col two, row three");
    tableTwoRowThree.getCell(2).setText("col three, row three");

    document.write(fos);
    fos.close();
    System.out.println("Success!");
   

上面的代码显示如下结果:

我想知道问题出在 LibreOffice 还是我的代码中。

【问题讨论】:

【参考方案1】:

创建具有LibreOffice Writer 也可以正常打开的表的*.xlsx 文件是绝对可能的。但是 Libreoffice/Openoffice 需要一个表格网格来接受列宽。

这应该可行:

import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;

import java.math.BigInteger;

public class CreateWordTable 
 public static void main(String[] args) throws Exception 

  XWPFDocument document = new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();

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

      //create first row
      XWPFTableRow tableRowOne = table.getRow(0);
      tableRowOne.getCell(0).setText("col one, row one");
      tableRowOne.addNewTableCell().setText("col two, row one");
      tableRowOne.addNewTableCell().setText("col three, row one");

  //create CTTblGrid for this table with widths of the 3 columns. 
  //necessary for Libreoffice/Openoffice to accept the column widths.
  //values are in unit twentieths of a point (1/1440 of an inch)
  //first column = 2 inches width
  table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  //other columns (2 in this case) also each 2 inches width
  for (int col = 1 ; col < 3; col++) 
   table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  

      //create second row
      XWPFTableRow tableRowTwo = table.createRow();
      tableRowTwo.getCell(0).setText("col one, row two");
      tableRowTwo.getCell(1).setText("col two, row two");
      tableRowTwo.getCell(2).setText("col three, row two");

      //create third row
      XWPFTableRow tableRowThree = table.createRow();
      tableRowThree.getCell(0).setText("col one, row three");
      tableRowThree.getCell(1).setText("col two, row three");
      tableRowThree.getCell(2).setText("col three, row three");

  paragraph = document.createParagraph();

  document.write(new FileOutputStream("CreateWordTable.docx"));
  document.close();

  System.out.println("CreateWordTable written successully");
 

另见Open office writer crashed when inserting table using java POI。

【讨论】:

【参考方案2】:

当我尝试在运行 Microsoft Office 的虚拟 Windows 10 机器上获取文件时,图形显示正确,因此我认为 LibreOffice 无法正确处理这些行并且仅显示文本。

问题已为我解决 - 下次我在 Microsoft Office 和 Windows 下测试我的所有文件。

【讨论】:

没必要那么快放弃。看我的回答。提示:*.docx 文件是包含XML 文件的ZIP 档案。所以我们可以使用LibreOffice创建*.docx,然后解压缩并查看XML,以确定LibreOffice是如何存储东西的。 我已经使用了您在上面提供的代码,但似乎 LibreOffice 没有按应有的方式可视化这些项目。此外 - 如果我在 .pdf 中转换 .docx,则这些行会在 Windows 和 Linux 的查看器中可视化。但是,此问题在 Windows、Microsoft Office 中不存在。由于大多数人使用的是 Windows,并且 .docx 中没有文档,而是在 .pdf 中,我不打算深入挖掘如何LibreOffice 在可视化内容方面发挥了魔力。谢谢@AxelRichter 的回答!

以上是关于XWPF 列超出 docx 文档边界(Ubuntu 16.04 主机)的主要内容,如果未能解决你的问题,请参考以下文章

使用python-docx处理word.docx文件

POI操作Word模板文本替换(表格文本替换)

docx4j导出word文档,有表格,如何固定word表格列宽,

Java将.docx文件转换为.pdf文件

python-docx设置docx文档表格样式

在 Java 中使用 Apache POI XWPF 在 Word 文档中的横向/纵向之间切换