顯示具有 Word 標籤的文章。 顯示所有文章
顯示具有 Word 標籤的文章。 顯示所有文章

2016年2月9日 星期二

使用 POI 讀取範例檔動態產生 word 報告

讀取 DB 產生一個個 word 報告時,通常不太可能用 POI 真的去慢慢產出 word 元素 一般會透過一個範本檔 .doc,再替換掉裡面的文字,如下範例

此範例使用到兩個 jar 檔,到 Apache POI 官網下載最新的 POI-3.13 ZIP 檔裡就會有這兩個檔案。

目錄結構如下,範本檔直接放在範例程式下

 


範本檔 student_template.doc 如下,內容可隨自己編排





範例程式 WordReportDemo01.java:


package demo.poi.word;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URISyntaxException;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Range;

/**
 * 透過 word 範本與 POI 產生報告
 * 
 * @author Rocky
 */
public class WordReportDemo01 {

 public static void main(String[] args) throws Exception {
  
  new WordReportDemo01().execute();
 }
 
 private void execute() throws Exception {
  
  Student student1 = new Student("子瑜", 79, "做的非常好");
  Student student2 = new Student("小明", 89, "記得多運動");

  createWordFile(student1);
  createWordFile(student2);
 }
 
 /**
  * 讀取範本並產生新報告
  * 
  * @param student
  * @throws IOException 
  * @throws URISyntaxException 
  */
 private void createWordFile(Student student) throws Exception {

  File tempFile = new File(WordReportDemo01.class.getResource("student_template.doc").toURI());
  File destFile = new File("D:/" + student.getName() + ".doc");
  
  InputStream is = new FileInputStream(tempFile);
  HWPFDocument doc = new HWPFDocument(is);
  Range range = doc.getRange(); // poi-scratchpad.jar

  // 依條件動態更換文字的顏色
  CharacterRun charRun = null;
  for (int i=0; i< range.numCharacterRuns(); i++) {
   charRun = range.getCharacterRun(i);
   if (! student.getName().equals("子瑜")) {
    if (charRun.text().equals("${score}") || charRun.text().equals("${comment}")) {
     charRun.setColor(6); // 設定為紅色
    } 
   }
  }

  // 替換範本檔中的文字
  range.replaceText("${name}", student.getName());
  range.replaceText("${score}", student.getScore() + "");
  range.replaceText("${comment}", student.getComment());

  // 寫出到新的 word 檔
  OutputStream os = new FileOutputStream(destFile);
  doc.write(os);
  
  os.close();
  is.close();
 }
 
 /**
  * Student Bean
  */
 class Student {
  
  private String name;
  /** 分數 */
  private int score;
  /** 評語 */
  private String comment;
  
  public Student(String name, int score, String comment) {
   this.name = name;
   this.score = score;
   this.comment = comment;
  }
  
  public String getName() {
   return name;
  }
  public void setName(String name) {
   this.name = name;
  }
  public int getScore() {
   return score;
  }
  public void setScore(int score) {
   this.score = score;
  }
  public String getComment() {
   return comment;
  }
  public void setComment(String comment) {
   this.comment = comment;
  }
 }
}
執行後即可在 D 槽下找到兩個新增的 word 檔