Apache POI - 如何将表从一个docx复制到另一个docx

时间:2020-12-13 20:24:31

Hi I am trying to copy a table from a docx file to another but what happens is that the value of the table are copied down bellow the table in the new document and outside of it (see pictures bellow)

嗨我正在尝试将一个表从docx文件复制到另一个,但是会发生的情况是表的值被复制到新文档中的表格之下并且在它之外(参见下面的图片)

Table in original docx Apache POI  - 如何将表从一个docx复制到另一个docx

原始docx中的表

Talbe in the new docx

Talbe在新的docx中

Apache POI  - 如何将表从一个docx复制到另一个docx

As you can see the values of the table are copied outside the table. I am using Libre Office, apache poi version 3.17 and my computer runs Ubuntu 16.04

如您所见,表的值将复制到表外。我正在使用Libre Office,apache poi版本3.17,我的电脑运行Ubuntu 16.04

The code I am using to perform the copy is the following

我用来执行复制的代码如下

public static void copyTable(XWPFDocument input_doc,XWPFDocument output_doc,
                             int table_index_input, int table_index_output) {

    XWPFTable template_table = input_doc.getTables().get(table_index_input);

    CTTbl ctTbl = CTTbl.Factory.newInstance(); // Create a new CTTbl for the new table
    ctTbl.set(template_table.getCTTbl()); // Copy the template table's CTTbl
    XWPFTable new_table = new XWPFTable(ctTbl, output_doc); // Create a new table using the CTTbl upon

    output_doc.createParagraph();
    output_doc.createTable();// Create a empty table in the document
    output_doc.setTable(table_index_output, new_table);  // Replace the empty table to table2

}

1 个解决方案

#1


2  

XWPFTable newTbl = output_doc.insertNewTbl(cursor);
copyTable(table, newTbl);

and the copyTable() method

和copyTable()方法

private void copyTable(XWPFTable source, XWPFTable target) {
    target.getCTTbl().setTblPr(source.getCTTbl().getTblPr());
    target.getCTTbl().setTblGrid(source.getCTTbl().getTblGrid());
    for (int r = 0; r<source.getRows().size(); r++) {
        XWPFTableRow targetRow = target.createRow();
        XWPFTableRow row = source.getRows().get(r);
        targetRow.getCtRow().setTrPr(row.getCtRow().getTrPr());
        for (int c=0; c<row.getTableCells().size(); c++) {
            //newly created row has 1 cell
            XWPFTableCell targetCell = c==0 ? targetRow.getTableCells().get(0) : targetRow.createCell();
            XWPFTableCell cell = row.getTableCells().get(c);
            targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
            XmlCursor cursor = targetCell.getParagraphArray(0).getCTP().newCursor();
            for (int p = 0; p < cell.getBodyElements().size(); p++) {
                IBodyElement elem = cell.getBodyElements().get(p);
                if (elem instanceof XWPFParagraph) {
                    XWPFParagraph targetPar = targetCell.insertNewParagraph(cursor);
                    cursor.toNextToken();
                    XWPFParagraph par = (XWPFParagraph) elem;
                    copyParagraph(par, targetPar);
                } else if (elem instanceof XWPFTable) {
                    XWPFTable targetTable = targetCell.insertNewTbl(cursor);
                    XWPFTable table = (XWPFTable) elem;
                    copyTable(table, targetTable);
                    cursor.toNextToken();
                }
            }
            //newly created cell has one default paragraph we need to remove
            targetCell.removeParagraph(targetCell.getParagraphs().size()-1);
        }
    }
    //newly created table has one row by default. we need to remove the default row.
    target.removeRow(0);
}

the copyParagraph()

private void copyParagraph(XWPFParagraph source, XWPFParagraph target) {
    target.getCTP().setPPr(source.getCTP().getPPr());
    for (int i=0; i<source.getRuns().size(); i++ ) {
        XWPFRun run = source.getRuns().get(i);
        XWPFRun targetRun = target.createRun();
        //copy formatting
        targetRun.getCTR().setRPr(run.getCTR().getRPr());
        //no images just copy text
        targetRun.setText(run.getText(0));
    }
}

#1


2  

XWPFTable newTbl = output_doc.insertNewTbl(cursor);
copyTable(table, newTbl);

and the copyTable() method

和copyTable()方法

private void copyTable(XWPFTable source, XWPFTable target) {
    target.getCTTbl().setTblPr(source.getCTTbl().getTblPr());
    target.getCTTbl().setTblGrid(source.getCTTbl().getTblGrid());
    for (int r = 0; r<source.getRows().size(); r++) {
        XWPFTableRow targetRow = target.createRow();
        XWPFTableRow row = source.getRows().get(r);
        targetRow.getCtRow().setTrPr(row.getCtRow().getTrPr());
        for (int c=0; c<row.getTableCells().size(); c++) {
            //newly created row has 1 cell
            XWPFTableCell targetCell = c==0 ? targetRow.getTableCells().get(0) : targetRow.createCell();
            XWPFTableCell cell = row.getTableCells().get(c);
            targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
            XmlCursor cursor = targetCell.getParagraphArray(0).getCTP().newCursor();
            for (int p = 0; p < cell.getBodyElements().size(); p++) {
                IBodyElement elem = cell.getBodyElements().get(p);
                if (elem instanceof XWPFParagraph) {
                    XWPFParagraph targetPar = targetCell.insertNewParagraph(cursor);
                    cursor.toNextToken();
                    XWPFParagraph par = (XWPFParagraph) elem;
                    copyParagraph(par, targetPar);
                } else if (elem instanceof XWPFTable) {
                    XWPFTable targetTable = targetCell.insertNewTbl(cursor);
                    XWPFTable table = (XWPFTable) elem;
                    copyTable(table, targetTable);
                    cursor.toNextToken();
                }
            }
            //newly created cell has one default paragraph we need to remove
            targetCell.removeParagraph(targetCell.getParagraphs().size()-1);
        }
    }
    //newly created table has one row by default. we need to remove the default row.
    target.removeRow(0);
}

the copyParagraph()

private void copyParagraph(XWPFParagraph source, XWPFParagraph target) {
    target.getCTP().setPPr(source.getCTP().getPPr());
    for (int i=0; i<source.getRuns().size(); i++ ) {
        XWPFRun run = source.getRuns().get(i);
        XWPFRun targetRun = target.createRun();
        //copy formatting
        targetRun.getCTR().setRPr(run.getCTR().getRPr());
        //no images just copy text
        targetRun.setText(run.getText(0));
    }
}