【问题标题】:XWPF - remove cell textXWPF - 删除单元格文本
【发布时间】:2016-02-07 00:38:12
【问题描述】:

我有一个包含单个表的 .docx 文件。我想从第 2 行到最后删除所有文本。 但是myTable.getRow(somecounter).getCell(somecounter2).setText("") 方法不起作用,因为它仅将“”连接到现有值。 我还尝试制作一个 XWPFRun 并执行从 myTable.getRow(sc).getCell(sc2).getParagraphs().get(0).createRun() 创建的 run.setText("") 但它也不起作用。

还尝试了this thread的解决方案,这次没有运气:(

任何想法如何轻松地从单元格中删除文本? 我的想法是从头开始制作一个新表并在其中填充内容,但这似乎真的很费力。

【问题讨论】:

    标签: java apache-poi xwpf


    【解决方案1】:

    由于Word 表格单元格可以包含除文本之外的许多其他内容,因此您的“从第 2 行到最后删除所有文本”的要求会有点复杂。

    考虑下表:

    因此,如果要求从第 2 行到最后删除 所有内容,那么您可以简单地将所有单元格替换为新的干净单元格。或者至少对于其中只有一个空段落的段落。

    import java.io.FileOutputStream;
    import java.io.FileInputStream;
    
    import java.util.List;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
    
    /*
    needs the full ooxml-schemas-1.3.jar as mentioned in https://poi.apache.org/faq.html#faq-N10025
    since the CTRowImpl is not fully shipped with poi-ooxml-schemas-3.13-*.jar
    */
    
    public class WordCleanTableRows {
    
     public static void main(String[] args) throws Exception {
    
      FileInputStream fis = new FileInputStream("document.docx");
      XWPFDocument doc = new XWPFDocument(fis);
    
      List<XWPFTable> tables = doc.getTables();
      XWPFTable table = tables.get(0);
    
      XWPFTableRow[] rows = table.getRows().toArray(new XWPFTableRow[0]);
      for (int r = 0; r < rows.length; r++) {
       if (r > 0) {
        XWPFTableRow row = rows[r];
        CTTc[] cells = row.getCtRow().getTcList().toArray(new CTTc[0]);
        for (int c = 0; c < cells.length; c++) {
         CTTc cTTc = cells[c];
         //clear only the paragraphs in the cell, keep cell styles
         cTTc.setPArray(new CTP[] {CTP.Factory.newInstance()});
         cells[c] = cTTc;
        }
        row.getCtRow().setTcArray(cells);
        //System.out.println(row.getCtRow());
       }
      }
    
      doc.write(new FileOutputStream("new document.docx"));
    
     }
    }
    

    这需要https://poi.apache.org/faq.html#faq-N10025 中提到的完整 ooxml-schemas-1.3.jar 因为 CTRowImpl 没有完全随 poi-ooxml-schemas-3.13-*.jar 一起提供。

    如果没有完整的 ooxml-schemas-1.3.jar,您可以简单地删除除第一行之外的所有行并添加新行。

    import java.io.FileOutputStream;
    import java.io.FileInputStream;
    
    import java.util.List;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    public class WordCleanTableRows2 {
    
     public static void main(String[] args) throws Exception {
    
      FileInputStream fis = new FileInputStream("document.docx");
      XWPFDocument doc = new XWPFDocument(fis);
    
      List<XWPFTable> tables = doc.getTables();
      XWPFTable table = tables.get(0);
    
      XWPFTableRow[] rows = table.getRows().toArray(new XWPFTableRow[0]);
      for (int r = 0; r < rows.length; r++) {
       if (r > 0) {
        XWPFTableRow row = rows[r];
        table.removeRow(1); //remove second row. others shift upwards
        table.createRow(); //add new row at the end
       }
      }
    
      doc.write(new FileOutputStream("new document.docx"));
    
     }
    }
    

    编辑:

    以下应该在没有 ooxml-schemas-1.3.jar 的情况下工作,并且与我的第一个示例相同。

    import java.io.FileOutputStream;
    import java.io.FileInputStream;
    
    import java.util.List;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
    
    import java.math.BigInteger;
    
    public class WordCleanTableRows3 {
    
     public static void main(String[] args) throws Exception {
    
      FileInputStream fis = new FileInputStream("document.docx");
      XWPFDocument doc = new XWPFDocument(fis);
    
      List<XWPFTable> tables = doc.getTables();
      XWPFTable table = tables.get(0);
    
      XWPFTableRow[] rows = table.getRows().toArray(new XWPFTableRow[0]);
      for (int r = 0; r < rows.length; r++) {
       if (r > 0) {
        XWPFTableRow row = rows[r];
        List<XWPFTableCell> cells = row.getTableCells();
        for (XWPFTableCell cell : cells) {
         //get CTTc and replace the CTPArray with one empty CTP
         cell.getCTTc().setPArray(new CTP[] {CTP.Factory.newInstance()});
    
         //set some default styles for the paragraphs in the cells:
         //http://grepcode.com/file/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/org/openxmlformats/schemas/wordprocessingml/x2006/main/CTParaRPr.java  
         CTP cTP = cell.getCTTc().getPArray(0);
         cTP.addNewPPr();
         cTP.getPPr().addNewRPr();
         cTP.getPPr().getRPr().addNewB().setVal(STOnOff.ON);
         cTP.getPPr().getRPr().addNewColor().setVal("FF0000");
         cTP.getPPr().getRPr().addNewSz().setVal(BigInteger.valueOf(40));
        }
       }
      }
    
      doc.write(new FileOutputStream("new document.docx"));
    
     }
    }
    

    org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP 随 poi-ooxml-schemas-3.13-*.jar 一起提供。

    【讨论】:

    • 要求是删除所有文本,但是单元格仅包含纯文本,没有其他内容,例如图像甚至空格,因此删除文本或内容都没有关系。您的解决方案似乎很好,尽管它在CTTc[] cells = row.getCtRow().getTcList().toArray(new CTTc[0]); 行给了我java.lang.NoClassDefFoundError: org/openxmlformats/schemas/wordprocessingml/x2006/main/impl/CTRowImpl$1TcList 这很奇怪,因为我有最新的 POI 版本(3.13)并且我已经添加了二进制版本中的所有文件。
    • 导入一些过时的 .jar 可以处理异常,但是循环连同内容一起删除了所有表格边框。我试图用table.setInsideHBorder(XWPFBorderType.SINGLE, 4, 0, "000000") 解决这个问题,但这显然只适用于内部边框,所以外部边框仍然不可见。页面方向也是垂直的,而它应该是水平的:(
    • 见我的补充。该方法去除了完整的细胞。所以当然所有的单元格样式也会被删除。我现在提供了一种方法,它只清除单元格中的段落并在我的第一个示例中保留单元格样式。但是删除和插入表格单元格将如何影响我无法重现的页面方向。
    • 第一种方法很有效,所以我不需要改变它。除了不存在的外部边框和错误的页面方向之外,其余的都可以。是否可以使用您的方法更改单元格内的文本格式(字体、粗体等)?另外非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多