【Java】【Word】 Word テンプレートを読み込んで、Javaで操作する [3] ~ Apache POI / 応用編 ~

はじめに

http://blogs.yahoo.co.jp/dk521123/36584422.html
http://blogs.yahoo.co.jp/dk521123/36584475.html
のコードを統合して整理する

# ループの嵐でパフォーマンス悪そうですが、そんなにハードに使わなければ問題ないかと...

サンプル

ValueReplacer.java

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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

public class ValueReplacer {
  public static void main(String[] args) {
    String inputFilePath = System.getProperty("user.dir") + "/template.docx";
    String outputFilePath = System.getProperty("user.dir") + "/output.docx";
    Map<String, String> mapper = new HashMap<String, String>() {
      private static final long serialVersionUID = 1L;
      {
        put("@@VER1@@", "Hello");
        put("@@VER2@@", "World");
        put("@@VER3@@", "Mike");
      }
    };

    try {
      replace(inputFilePath, outputFilePath, mapper);
    } catch (FileNotFoundException ex) {
      ex.printStackTrace();
    } catch (IOException ex) {
      ex.printStackTrace();
    }

    System.out.println("Done. See " + outputFilePath);
  }

  public static void replace(String inputTemplateWordFile, String outputWordFile, Map<String, String> convertMapping)
      throws FileNotFoundException, IOException {
    try (XWPFDocument document = new XWPFDocument(new FileInputStream(inputTemplateWordFile));) {
      replaceValues(document, convertMapping);
      replaceValuesInTables(document, convertMapping);

      save(document, outputWordFile);
    }
  }

  private static void save(XWPFDocument document, String outputWordFile) throws FileNotFoundException, IOException {
    document.write(new FileOutputStream(outputWordFile));
  }

  private static void replaceValues(XWPFDocument document, Map<String, String> convertMapping) {
    for (XWPFParagraph paragraph : document.getParagraphs()) {
      StringBuilder stringBuilder = new StringBuilder();
      for (XWPFRun run : paragraph.getRuns()) {
        int position = run.getTextPosition();
        if (run.getText(position) != null) {
          stringBuilder.append(run.getText(position));
        }
      }

      for (Map.Entry<String, String> map : convertMapping.entrySet()) {
        if (stringBuilder.length() > 0 && stringBuilder.toString().contains(map.getKey())) {
          for (int i = 0; i < paragraph.getRuns().size(); i++) {
            paragraph.removeRun(i);
          }

          String text = stringBuilder.toString().replace(map.getKey(), map.getValue());
          XWPFRun run = paragraph.createRun();
          run.setText(text);
          paragraph.addRun(run);
        }
      }
    }
  }

  private static void replaceValuesInTables(XWPFDocument document, Map<String, String> convertMapping) {
    for (XWPFTable table : document.getTables()) {
      for (XWPFTableRow tableRow : table.getRows()) {
        for (XWPFTableCell tableCell : tableRow.getTableCells()) {
          String tableCellValue = tableCell.getText();
          if (tableCellValue == null || tableCellValue.isEmpty()) {
            continue;
          }

          for (Map.Entry<String, String> map : convertMapping.entrySet()) {
            if (tableCellValue.contains(map.getKey())) {
              String replaecedText = tableCellValue.replace(map.getKey(), map.getValue());
              removeParagraphs(tableCell);
              tableCell.setText(replaecedText);
            }
          }
        }
      }
    }
  }

  private static void removeParagraphs(XWPFTableCell tableCell) {
    for (int i = 0; i < tableCell.getParagraphs().size(); i++) {
      tableCell.removeParagraph(i);
    }
  }
}

関連記事

Java で Word の読み書きを行う ~ Apache POI / 入門編 ~

http://blogs.yahoo.co.jp/dk521123/36584129.html

Word テンプレートを読み込んで、Javaで操作する [1] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584422.html

Word テンプレートを読み込んで、Javaで操作する [2] ~ Apache POI / 応用編 ~

http://blogs.yahoo.co.jp/dk521123/36584475.html