poi操作表格table

转载,原文地址:
https://github.com/Sayi/sayi.github.com/issues/21

表格对于页面的布局具有重大的意义,正因为其灵活性,所以用模板引擎处理word中的Table时,显得并不是那么简单,本文将讨论如何利用poi-tl(1.2.0版本)提供的工具来简化表格处理。关于如何使用poi-tl,参见中文Wiki

表格模板

poi-tl默认实现了N行N列的样式(如下图),同时提供了当数据为空时,展示一行空数据的文案(如下图中的No Data Descs)。
image

在poi-tl的1.2.0版本中,表格模板语法是#,数据结构是com.deepoove.poi.data.TableRenderData。
1. 表格头使用headers[]定义,支持设置背景色
2. 表格数据使用datas[]定义,不同列的数据在datas中使用分号隔开
3. 宽度使用width定义
4. 无数据文案使用noDatadesc定义

{
  "datas": [
    "beijing;beijing",
    "zhejiang;hangzhou"
  ],
  "headers": [
    {
      "style": {
        "color": "1E915D",
        "fontSize": 0
      },
      "text": "province"
    },
    {
      "style": {
        "color": "1E915D",
        "fontSize": 0
      },
      "text": "city"
    }
  ],
  "noDatadesc": "no datas",
  "width": 0
}

具体Java代码参考:

@Test
public void testTable() throws Exception {
  Map<String, Object> datas = new HashMap<String, Object>() {
    {
      // 有表格头 有数据
      put("table", new TableRenderData(new ArrayList<RenderData>() {
        {
          add(new TextRenderData("1E915D", "province"));
          add(new TextRenderData("1E915D", "city"));
        }
      }, new ArrayList<Object>() {
        {
          add("beijing;beijing");
          add("zhejiang;hangzhou");
        }
      }, "no datas", 0));
    }
  };
  XWPFTemplate template = XWPFTemplate.compile("src/test/resources/table.docx").render(datas);

  FileOutputStream out = new FileOutputStream("out_table.docx");
  template.write(out);
  out.flush();
  out.close();
  template.close();
}

表格的宽度怎么定义的

是一个点的二十分之一,或者是1440分之一英寸。官方解释如下:

dxa - Specifies that the value is in twentieths of a point (1/1440 of an inch).
首先1英寸=2.54厘米,A4纸大小为21cm*29.7cm。
如果这个width设置成5670,则表示这个表格的宽度是10cm。

抛开对这个单位理解的难度,我们最常见的应该是宽度自适应和宽度最大。
如果在poi-tl中设置了width=0,则表格是宽度自适应的。
以A4纸为例,页面宽度为21cm,左右页边距各位3.17cm,则表格的width=(21-3.17*2)/2.54*1440,大约为8310。

合并单元格

但是,很多业务场景并不仅限于如此简单的表格布局,产品需求总是丰富多彩的。poi-tl对XWPFDocument进行了封装,增强实现了一些基本功能。在com.deepoove.poi.NiceXWPFDocument中提供了合并的功能。

/**
 * 合并行单元格
 * @param table
 * @param row
 * @param fromCol
 * @param toCol
 */
public void mergeCellsHorizonal(XWPFTable table, int row, int fromCol,
    int toCol)

/**
 * 合并列单元格
 * @param table
 * @param col
 * @param fromRow
 * @param toRow
 */
public void mergeCellsVertically(XWPFTable table, int col, int fromRow,
    int toRow)

自定义表格之新建表格

我们完全可以从无到有去创建一个新的表格。

  1. 无需事先创建表格,在docx中,直接输入{{table}}
  2. 默认{{table}}是文本模板,我们需要通过registerPolicy设置此模板为自定义模板。
XWPFTemplate template = XWPFTemplate.compile("src/test/resources/complex.docx");
template.registerPolicy("table", new MyTableRenderPolicy());
  1. 新建MyTableRenderPolicy.java,实现RenderPolicy接口
@Override
public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
  NiceXWPFDocument doc = template.getXWPFDocument();
  RunTemplate runTemplate = (RunTemplate) eleTemplate;
  XWPFRun run = runTemplate.getRun();
  if (null == data) return;

  //doc.insertNewTable(run, row, col);
  //doc.mergeCellsHorizonal(table, 1, 0, 1);
  //...
  runTemplate.getRun().setText("", 0);
}

至此,我们持有了NiceXWPFDocument和XWPFRun对象,可以插入表格,合并单元格等操作。

自定义表格之动态处理已有表格

对于事先已知道部分表格样式,我们只需要处理剩余部分的表格可以采用此方式。

比如下图,我们在模板中设计好表格头和表格未的样式,表格中间的数据则可以动态处理。
image

  1. 定义如图的模板,在表格内输入模板元素{{table}}
  2. 通过registerPolicy设置此模板为自定义模板
  3. 新建MyTableRenderPolicy.java,继承DynamicTableRenderPolicy
public class MyTableRenderPolicy extends DynamicTableRenderPolicy {

  @Override
  public void render(XWPFTable table, Object data) {
      //table.getRow(1).getCell(0)
      //XWPFTableRow row = table.insertNewTableRow(1);
      //table.removeRow(1);
  }
}

至此,我们可以通过XWPFTable对象对表格进行删除行列、增加行列、设置文字等操作。

<think>首先,用户的问题是关于使用Apache POI 5.2.2中的HWPFDocument来操作Word文档中的表格。我需要根据系统级指令来构建我的回答。 系统级指令要点: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考提供的引用内容,但这些引用主要是关于XWPF的,不是HWPF。引用[1]提到XWPF用于处理.docx格式,而HWPF用于处理.doc格式。用户指定了HWPFDocument,所以是针对.doc格式的文档。 用户的问题:"我想使用POI 5.2.2中的HWPFDocument操作Word文档中的表格 请问Apache POI 5.2.2 HWPFDocument 操作 Word 表格 教程" 关键点: - HWPFDocument是Apache POI中用于处理旧版Word文档(.doc格式)的类。 - 用户想操作Word文档中的表格。 - 我需要提供一个教程式的回答,逐步指导。 我的回答结构: 1. **介绍HWPFDocument**:解释HWPFDocument是什么,它与XWPF的区别(因为引用中提到了XWPF)。 2. **基本步骤**:包括如何添加依赖、创建文档、操作表格等。 3. **代码示例**:提供Java代码示例,展示如何创建表格、添加行和单元格等。 4. **注意事项**:提到HWPF的局限性和在Android开发中的问题(如内存限制,引用[3]提到过)。 5. **生成相关问题**:在末尾添加相关问题。 参考提供的引用: - 引用[1]:讨论XWPF用于.docx。 - 引用[2]:关于Apache POI的基本实践。 - 引用[3]:在Android开发中使用Apache POI的挑战。 由于用户指定了HWPFDocument,我应该强调它用于.doc格式,并可能提到在较新版本中,.docx使用XWPF更常见。 回答大纲: - **步骤1:添加依赖**:如何在项目中添加Apache POI 5.2.2的依赖。 - **步骤2:创建HWPFDocument**:如何创建一个新的文档或加载现有文档。 - **步骤3:操作表格**:如何添加、修改或删除表格。 - 创建表格。 - 添加行和单元格。 - 设置单元格内容。 - **步骤4:保存文档**。 - **代码示例**:提供一个简单的Java示例。 - **注意事项**:HWPF的局限性,如在Android中的内存问题(参考引用[3])。 生成相关问题: - 类似于示例中的格式,列出2-3个相关问题。 确保语言为中文。 现在,构建回答: - 开头介绍HWPFDocument。 - 然后逐步指导。 - 代码块使用适当的格式。 - 末尾添加相关问题。 数学表达式:由于主题是编程,可能没有数学表达式,但如果有,要用LaTeX格式。这里可能不需要。 引用标识:在回答中,如果引用外部知识或提供的引用,添加[^n]。例如,提到HWPF用于.doc格式时,可以引用Apache POI文档,但用户没有提供具体引用源。我可以使用提供的引用[1]、[2]、[3]作为参考,但需要自然添加。 例如: - 当提到HWPF和XWPF的区别时,可以说:HWPF用于处理旧版.doc格式,而XWPF用于新版.docx格式[^1]。 - 当提到内存限制时,可以说:在Android开发中,处理文档时需注意内存限制[^3]。 代码示例:使用Java代码,因为Apache POIJava库。 具体步骤: 1. 添加Maven依赖或Gradle依赖。 2. 导入必要类。 3. 创建或加载文档。 4. 操作表格。 5. 保存文档。 HWPFDocument操作表格的API: - 使用Table类。 - 创建表格:document.getRange().insertTable(...) - 添加行:table.getRow(...) 或创建新行。 - 添加单元格:row.getCell(...) 或创建新单元格。 提供一个简单示例。</think>### Apache POI 5.2.2 HWPFDocument 操作 Word 表格教程 Apache POI 是一个强大的 Java 库,用于操作 Microsoft Office 文档。其中,HWPFDocument 组件专门用于处理旧版 Word 文档(.doc 格式),而 XWPF 则用于新版 .docx 格式(基于 Open XML 标准)[^1]。本教程将指导您如何在 Apache POI 5.2.2 中使用 HWPFDocument 操作 Word 文档中的表格。内容包括添加依赖、创建文档、操作表格(如添加、修改行和单元格),以及保存文档。教程基于 Java 实现,并包含完整代码示例。 --- #### 步骤 1: 添加 Apache POI 5.2.2 依赖 在项目中添加 Apache POI 的依赖。如果您使用 Maven,在 `pom.xml` 中添加以下内容: ```xml <dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>5.2.2</version> <!-- 包含 HWPF 组件 --> </dependency> </dependencies> ``` 如果您使用 Gradle,在 `build.gradle` 中添加: ```groovy dependencies { implementation 'org.apache.poi:poi:5.2.2' implementation 'org.apache.poi:poi-scratchpad:5.2.2' } ``` **注意**:HWPFDocument 属于 `poi-scratchpad` 模块,专门处理 .doc 格式。确保版本一致以避免兼容性问题。 --- #### 步骤 2: 创建或加载 HWPFDocument HWPFDocument 用于表示一个 Word 文档。您可以从文件加载或创建一个新文档: - **加载现有文档**:使用文件输入流。 - **创建新文档**:直接实例化 HWPFDocument。 ```java import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Range; import java.io.FileInputStream; import java.io.FileOutputStream; public class HWPFTableExample { public static void main(String[] args) { try { // 创建新文档(或加载现有文档) HWPFDocument document = new HWPFDocument(); // 创建新文档 // 如需加载现有文档:HWPFDocument document = new HWPFDocument(new FileInputStream("template.doc")); // 获取文档范围,用于操作内容 Range range = document.getRange(); // 后续步骤:操作表格 // ... // 保存文档 document.write(new FileOutputStream("output.doc")); document.close(); System.out.println("文档保存成功!"); } catch (Exception e) { e.printStackTrace(); } } } ``` --- #### 步骤 3: 操作 Word 表格 在 HWPFDocument 中,表格操作主要通过 `Table` 类实现。您可以创建表格、添加行和单元格、设置内容等。以下是关键操作: 1. **创建表格**: - 使用 `range.insertTable()` 方法插入一个新表格。 - 参数:列数、行数、表格宽度(单位:twips,1 inch = 1440 twips)。 2. **添加行和单元格**: - 获取表格对象后,通过 `getRow()` 和 `getCell()` 访问行和单元格。 - 设置单元格内容使用 `cell.text()`。 3. **修改表格属性**(可选): - 设置边框、背景色等(但 HWPF 对高级样式的支持有限)。 **完整代码示例**:创建一个包含 2 行 3 列的表格,并填充数据。 ```java import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.hwpf.usermodel.Table; import org.apache.poi.hwpf.usermodel.TableCell; import org.apache.poi.hwpf.usermodel.TableRow; import java.io.FileOutputStream; public class HWPFTableExample { public static void main(String[] args) { try { HWPFDocument document = new HWPFDocument(); Range range = document.getRange(); // 步骤 3.1: 创建表格(3列2行,宽度为 5000 twips) Table table = range.insertTable(3, 2, 5000); // 步骤 3.2: 填充表格内容 // 第一行 TableRow row1 = table.getRow(0); TableCell cell11 = row1.getCell(0); TableCell cell12 = row1.getCell(1); TableCell cell13 = row1.getCell(2); cell11.text().replaceText("姓名", false); // false 表示不替换样式 cell12.text().replaceText("年龄", false); cell13.text().replaceText("职业", false); // 第二行 TableRow row2 = table.getRow(1); TableCell cell21 = row2.getCell(0); TableCell cell22 = row2.getCell(1); TableCell cell23 = row2.getCell(2); cell21.text().replaceText("张三", false); cell22.text().replaceText("30", false); cell23.text().replaceText("工程师", false); // 保存文档 document.write(new FileOutputStream("output.doc")); document.close(); System.out.println("表格创建成功!"); } catch (Exception e) { e.printStackTrace(); } } } ``` **关键说明**: - **表格索引**:行和列索引从 0 开始(例如,`table.getRow(0)` 获取第一行)。 - **内容设置**:`replaceText()` 方法用于设置文本,第二个参数 `false` 保留原有样式。 - **样式限制**:HWPF 对表格样式的支持较弱(如边框、颜色),如果需要高级格式,建议使用 XWPF(针对 .docx)[^1]。 --- #### 注意事项 1. **HWPF 的局限性**:HWPFDocument 主要用于旧版 .doc 格式,功能不如 XWPF(针对 .docx)丰富。例如,复杂表格操作可能受限,且文档生成效率较低[^1][^2]。 2. **Android 开发问题**:在 Android 应用中,Apache POI 可能导致内存溢出(OOM),因为 HWPF 处理大型文档时占用内存较高。建议: - 使用模板文件减少内存开销。 - 在后台线程处理文档操作。 - 考虑替代方案如 XWPF(如果目标格式是 .docx)[^3]。 3. **兼容性**:确保使用 POI 5.2.2 版本,避免旧版 API 不兼容问题。 --- #### 相关问题 1. 如何在 Apache POI 中使用 HWPFDocument 加载和修改现有 Word 文档中的表格? 2. HWPFDocument 和 XWPFDocument 在处理表格时有哪些主要区别? 3. 在 Android 应用中集成 Apache POI 时,如何优化内存使用以避免崩溃?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值