Java Apache POI 5.0创建XSLFTable

Java Apache POI 5.0创建XSLFTable,java,apache-poi,Java,Apache Poi,我尝试为幻灯片创建一个简单的表格 我正在使用以下代码: XSLFTable tbl = slide.createTable(); tbl.setAnchor(anchor); XSLFTableRow row1 = tbl.addRow(); row1.addCell().setText("Cell 1.1"); XSLFTableCell cell = row1.addCell

我尝试为幻灯片创建一个简单的表格

我正在使用以下代码:

        XSLFTable tbl = slide.createTable();
        tbl.setAnchor(anchor);
        
        XSLFTableRow row1 = tbl.addRow();
        row1.addCell().setText("Cell 1.1");
        XSLFTableCell cell = row1.addCell();
        cell.setText("Cell 1.2");
            
        XSLFTableRow row2 = tbl.addRow();
        row2.addCell().setText("Cell 2.1");
        cell = row2.addCell();
        cell.setText("Cell 2.2");
但结果很奇怪——见图

我做错了什么还是一只虫子


谢谢你的帮助

Apache-poi
在创建类似于
Word
的表时存在多个问题。而
PowerPoint
表格也与
Word
表格类似。这些问题源于创建表、行和单元格的方法中的一些奇怪的决定。这些决定会随着版本的变化而变化。因此,在从一个版本更新到另一个版本后,您始终需要检查“新建”

在本例中,
xslttable.addRow
从上面的行中接管所有存在的单元格。如果第一行已经有两个单元格,现在正在创建第二行,那么第二行也已经有两个单元格了。如果随后将新单元格添加到第二行,则第二行的多于两个单元格。这导致了奇怪的渲染结果

因此,当前(
ApachePOI5.0.0
),您只需要将新单元格添加到第一行。添加第二行后,该行已包含单元格,您只需为其设置值:

 XSLFTable tbl;
 XSLFTableRow row;
 XSLFTableCell cell;
  
 tbl = slide.createTable();
 tbl.setAnchor(anchor);
  
 row = tbl.addRow();
 cell = row.addCell();
 cell.setText("Cell 1.1");
 cell = row.addCell();
 cell.setText("Cell 1.2");
  
 row = tbl.addRow();
 cell = tbl.getCell(1, 0);
 cell.setText("Cell 2.1");
 cell = tbl.getCell(1, 1);
 cell.setText("Cell 2.2");
当然,在多个行和单元格中为表设置值不是很方便。有
XSLFSheet.createTable(int-numRows,int-numCols)
可以创建一个已经包含所有所需单元格的表,因此我们只需要设置单元格值即可。但这会产生与您所做的相同的错误,因此也会导致不正确的表。它还将单元格添加到新创建的行中,尽管这些行在创建时已经从上面的行中获取了单元格。似乎一个开发人员不知道另一个开发人员的决定

因此,我们需要对
XSLFSheet.createTable(intnumrows,intnumcols)
进行错误修复

以下完整示例显示了上述所有内容:

import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.TableCell.BorderEdge;

import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Color;

public class CreatePPTXTable {
    
 //bug fix to https://svn.apache.org/viewvc/poi/tags/REL_5_0_0/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java?view=markup#l289
 //creates new cells in all new rows and so damages the table
 static XSLFTable createTable(XSLFSheet sheet, int numRows, int numCols) throws Exception {
  if (numRows < 1 || numCols < 1) {
   throw new IllegalArgumentException("numRows and numCols must be greater than 0");
  }
  XSLFTable sh = sheet.createTable();
  for (int r = 0; r < numRows; r++) {
   XSLFTableRow row = sh.addRow(); // this takes over all cells from present rows
   if (r == 0) { // so add new cells only in first row
    for (int c = 0; c < numCols; c++) {
     row.addCell();
    }
   }
  }
  return sh;
 }
    
 static void setAllCellBorders(XSLFTableCell cell, Color color) {
  cell.setBorderColor(BorderEdge.top, color);
  cell.setBorderColor(BorderEdge.right, color);
  cell.setBorderColor(BorderEdge.bottom, color);
  cell.setBorderColor(BorderEdge.left, color);
 }

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

  XMLSlideShow ppt = new XMLSlideShow();

  XSLFSlide slide = ppt.createSlide();
  
  XSLFTable tbl;
  XSLFTableRow row;
  XSLFTableCell cell;
  
  tbl = slide.createTable();
  tbl.setAnchor(new Rectangle(new Point(100, 100)));
  
  row = tbl.addRow();
  cell = row.addCell(); setAllCellBorders(cell, Color.BLACK);
  cell.setText("Cell 1.1");
  cell = row.addCell(); setAllCellBorders(cell, Color.BLACK);
  cell.setText("Cell 1.2");
  
  row = tbl.addRow();
  cell = tbl.getCell(1, 0); setAllCellBorders(cell, Color.BLACK);
  cell.setText("Cell 2.1");
  cell = tbl.getCell(1, 1); setAllCellBorders(cell, Color.BLACK);
  cell.setText("Cell 2.2");
  
  
  String[][] data = {
   {"R1C1", "R1C2", "R1C3"},
   {"R2C1", "R2C2", "R2C3"},
   {"R3C1", "R3C2", "R3C3"}
  };
  
  tbl = createTable(slide, data.length, data[0].length);
  tbl.setAnchor(new Rectangle(new Point(100, 300)));

  for (int r = 0; r < data.length; r++) {
   String[] dataRow = data[r];
   for (int c = 0; c < dataRow.length; c++) {
    String value = dataRow[c];
    cell = tbl.getCell(r, c);
    setAllCellBorders(cell, Color.BLACK);
    cell.setText(value);
   }
  }  

  FileOutputStream out = new FileOutputStream("fileName.pptx");
  ppt.write(out);
  out.close();
 }
}
import java.io.FileOutputStream;
导入org.apache.poi.xslf.usermodel.*;
导入org.apache.poi.sl.usermodel.TableCell.BorderEdge;
导入java.awt.Rectangle;
导入java.awt.Point;
导入java.awt.Color;
公共类CreatePPTXTable{
//错误修复到https://svn.apache.org/viewvc/poi/tags/REL_5_0_0/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java?view=markup#l289
//在所有新行中创建新单元格,从而损坏表
静态XSLFTable createTable(XSLFSheet sheet、int numRows、int numCols)引发异常{
如果(numRows<1 | | numCols<1){
抛出新的IllegalArgumentException(“numRows和numCols必须大于0”);
}
xslttable sh=sheet.createTable();
对于(int r=0;r
你好,Axel,非常感谢您详细易懂的解释!这对我帮助很大!感谢和欢迎此问题是在5.0.0发布后发布的,因此5.0.1将与4.1.2一样工作。阿克塞尔是对的,有时候我们不知道其他提交人在做什么-我希望(问他是否…)他愿意成为团队的一员,因为我很荣幸他对stackoverflow的贡献。。。但遗憾的是,他拒绝了。是此问题的电子邮件线程。