Заменить значение столбца таблицы в Apache POI - PullRequest
2 голосов
/ 06 декабря 2011

Я использую Apache POI 3.7.Я пытаюсь заменить значение столбца таблицы в документе Word (DOCX).Тем не менее, я продолжил добавлять значение текущего значения в документ.Но если значение столбца таблицы равно нулю, оно помещает значение.Можете ли вы дать мне несколько мыслей, как решить эту проблему.Ниже приведен код, который я сделал до сих пор.

Заранее спасибо.

package test.doc;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

public class POIDocXTableTest {

    public static void main(String[] args)throws IOException {
        String fileName = "C:\\Test.docx";
        InputStream fis = new FileInputStream(fileName);
        XWPFDocument document = new XWPFDocument(fis);
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (int x=0; x<paragraphs.size();x++)
        {
            XWPFParagraph paragraph = paragraphs.get(x);
            System.out.println(paragraph.getParagraphText());
        }
        List<XWPFTable> tables = document.getTables();
        for (int x=0; x<tables.size();x++)
        {
            XWPFTable table = tables.get(x);
            List<XWPFTableRow> tableRows = table.getRows();
            tableRows.remove(x);
            for (int r=0; r<tableRows.size();r++)
            {
                System.out.println("Row "+ (r+1)+ ":");
                XWPFTableRow tableRow = tableRows.get(r);
                List<XWPFTableCell> tableCells = tableRow.getTableCells();
                for (int c=0; c<tableCells.size();c++)
                {
                    System.out.print("Column "+ (c+1)+ ": ");
                    XWPFTableCell tableCell = tableCells.get(c);
                    //tableCell.setText("TAE");
                    String tableCellVal = tableCell.getText();
                    if ((c+1)==2){
                        if (tableCellVal!=null){
                            if (tableCellVal.length()>0){
                                 char c1 = tableCellVal.charAt(0);
                                 String s2 = "-TEST";
                                 char c2 = s2.charAt(0);
                                 String test = tableCell.getText().replace(tableCellVal,s2);
                                 tableCell.setText(test);
                            }else{
                                //tableCell.setText("NULL");
                            }
                        }
                    }
                    System.out.println("tableCell.getText(" + (c) + "):" + tableCellVal);
                }
            }
            System.out.println("\n");
        }
        OutputStream out = new FileOutputStream(fileName);
        document.write(out);
        out.close();
    }
}

Ответы [ 2 ]

6 голосов
/ 26 февраля 2015

Лучшим решением для предотвращения стилей в абзацах и поиска строк поиска с разными стилями является этот метод:

  private long replaceInParagraphs(Map<String, String> replacements, List<XWPFParagraph> xwpfParagraphs) {
    long count = 0;
    for (XWPFParagraph paragraph : xwpfParagraphs) {
      List<XWPFRun> runs = paragraph.getRuns();

      for (Map.Entry<String, String> replPair : replacements.entrySet()) {    
        String find = replPair.getKey();
        String repl = replPair.getValue();
        TextSegement found = paragraph.searchText(find, new PositionInParagraph());
        if ( found != null ) {
          count++;
          if ( found.getBeginRun() == found.getEndRun() ) {
            // whole search string is in one Run
           XWPFRun run = runs.get(found.getBeginRun());
           String runText = run.getText(run.getTextPosition());
           String replaced = runText.replace(find, repl);
           run.setText(replaced, 0);
          } else {
            // The search string spans over more than one Run
            // Put the Strings together
            StringBuilder b = new StringBuilder();
            for (int runPos = found.getBeginRun(); runPos <= found.getEndRun(); runPos++) {
              XWPFRun run = runs.get(runPos);
              b.append(run.getText(run.getTextPosition()));
            }                       
            String connectedRuns = b.toString();
            String replaced = connectedRuns.replace(find, repl);

            // The first Run receives the replaced String of all connected Runs
            XWPFRun partOne = runs.get(found.getBeginRun());
            partOne.setText(replaced, 0);
            // Removing the text in the other Runs.
            for (int runPos = found.getBeginRun()+1; runPos <= found.getEndRun(); runPos++) {
              XWPFRun partNext = runs.get(runPos);
              partNext.setText("", 0);
            }                          
          }
        }
      }      
    }
    return count;
  }

Этот метод работает со строками поиска, охватывающими более одного прогона.Замененная часть получает стиль из первого найденного прогона.

3 голосов
/ 14 ноября 2013

хорошо, я сделал что-то подобное, чтобы заменить метки в шаблоне слова указанными словами ...:

    public DotxTemplateFiller() {
    String filename = "/poi/ls_Template_modern_de.dotx";
    String outputPath = "/poi/output/output" + new Date().getTime()
            + ".dotx";
    OutputStream out = null;
    try {
        File file = new File(filename);
        XWPFDocument template = new XWPFDocument(new FileInputStream(file));

        List<XWPFParagraph> xwpfParagraphs = template.getParagraphs();
        replaceInParagraphs(xwpfParagraphs);

        List<XWPFTable> tables = template.getTables();
        for (XWPFTable xwpfTable : tables) {
            List<XWPFTableRow> tableRows = xwpfTable.getRows();
            for (XWPFTableRow xwpfTableRow : tableRows) {
                List<XWPFTableCell> tableCells = xwpfTableRow
                        .getTableCells();
                for (XWPFTableCell xwpfTableCell : tableCells) {
                    xwpfParagraphs = xwpfTableCell.getParagraphs();
                    replaceInParagraphs(xwpfParagraphs);
                }
            }
        }

        out = new FileOutputStream(new File(outputPath));
        template.write(out);
        out.flush();
        out.close();
        //System.exit(0);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                // nothing to do ....
            }
        }
    }
}

/**
 * @param xwpfParagraphs
 */
private void replaceInParagraphs(List<XWPFParagraph> xwpfParagraphs) {
    for (XWPFParagraph xwpfParagraph : xwpfParagraphs) {
        List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();
        for (XWPFRun xwpfRun : xwpfRuns) {
            String xwpfRunText = xwpfRun.getText(xwpfRun
                    .getTextPosition());
            for (Map.Entry<String, String> entry : replacements
                    .entrySet()) {
                if (xwpfRunText != null
                        && xwpfRunText.contains(entry.getKey())) {
                    xwpfRunText = xwpfRunText.replaceAll(
                            entry.getKey(), entry.getValue());
                }
            }
            xwpfRun.setText(xwpfRunText, 0);
        }
    }
}

public static void main(String[] args) {
    new DotxTemplateFiller();
}

Сначала я сделал это для обычных абзацев в шаблоне MS Word, а затем для абзацев внутри ячеек таблицы. Надеюсь, что это полезно для вас, и я надеюсь, что я правильно понял вашу проблему ...: -)

С наилучшими пожеланиями.

...