java Apache poi 워드 doc 파일 읽 기와 쓰기

POI 로 Word doc 파일 읽 기
       Apache poi 의 hwpf 모듈 은 워드 doc 파일 을 읽 고 쓰 는 데 사 용 됩 니 다.hwpf 에서 우 리 는 HWPFDocument 을 사용 하여 워드 doc 문 서 를 표시 합 니 다.HWPFDocument 에는 다음 과 같은 몇 가지 개념 이 있 습 니 다.
  Range:이 범 위 는 전체 문서 일 수도 있 고 안의 한 소절(Section)일 수도 있 으 며 특정한 단락(Paragraph)일 수도 있 고 공 통 된 속성 을 가 진 텍스트(CharacterRun)일 수도 있 습 니 다.
  Section:워드 문서 의 한 소절,하나의 워드 문 서 는 여러 소절 로 구성 할 수 있 습 니 다.
  Paragraph:word 문서 의 한 단락,한 소절 은 여러 단락 으로 구성 할 수 있 습 니 다.
  CharacterRun:같은 속성 을 가 진 텍스트 입 니 다.한 단락 은 여러 개의 CharacterRun 으로 구성 할 수 있 습 니 다.
  Table:표 하나.
  TableRow:표 에 대응 하 는 줄 입 니 다.
  TableCell:표 에 대응 하 는 셀 입 니 다.
       Section,Paragraph,CharacterRun,Table 은 모두 Range 에서 계승 된다.
1       워드 doc 파일 읽 기
       일상적인 응용 프로그램 에서 워드 파일 에서 정 보 를 읽 는 경 우 는 매우 드 물 며,더 많은 것 은 워드 파일 에 내용 을 기록 하 는 것 입 니 다.POI 를 사용 하여 워드 doc 파일 에서 데 이 터 를 읽 을 때 주로 두 가지 방법 이 있 습 니 다.워드 Extractor 를 통 해 읽 고 HWPFDocument 을 통 해 읽 습 니 다.WordExtractor 내부 에서 정 보 를 읽 을 때 도 HWPFDocument 을 통 해 얻 을 수 있 습 니 다.
1.1     WordExtractor 를 통 해 파일 읽 기
       워드 Extractor 를 사용 하여 파일 을 읽 을 때 우 리 는 파일 의 텍스트 내용 과 문서 기반 의 일부 속성 만 읽 을 수 있 고 문서 내용 의 속성 등 은 읽 을 수 없습니다.문서 내용 의 속성 을 읽 으 려 면 HWPFDocument 을 사용 하여 읽 어야 합 니 다.다음은 WordExtractor 를 사용 하여 파일 을 읽 는 예제 입 니 다.

public class HwpfTest {
 
  @SuppressWarnings("deprecation")
  @Test
  public void testReadByExtractor() throws Exception {
   InputStream is = new FileInputStream("D:\\test.doc");
   WordExtractor extractor = new WordExtractor(is);
   //  word       
   System.out.println(extractor.getText());
   System.out.println(extractor.getTextFromPieces());
   //       
   System.out.println("  :" + extractor.getHeaderText());
   //       
   System.out.println("  :" + extractor.getFooterText());
   //    word        ,    、        。
   System.out.println(extractor.getMetadataTextExtractor().getText());
   //         
   String paraTexts[] = extractor.getParagraphText();
   for (int i=0; i<paraTexts.length; i++) {
     System.out.println("Paragraph " + (i+1) + " : " + paraTexts[i]);
   }
   //    word     
   printInfo(extractor.getSummaryInformation());
   //    word     
   this.printInfo(extractor.getDocSummaryInformation());
   this.closeStream(is);
  }
 
  /**
  *   SummaryInfomation
  * @param info
  */
  private void printInfo(SummaryInformation info) {
   //  
   System.out.println(info.getAuthor());
   //    
   System.out.println(info.getCharCount());
   //  
   System.out.println(info.getPageCount());
   //  
   System.out.println(info.getTitle());
   //  
   System.out.println(info.getSubject());
  }
 
  /**
  *   DocumentSummaryInfomation
  * @param info
  */
  private void printInfo(DocumentSummaryInformation info) {
   //  
   System.out.println(info.getCategory());
   //  
   System.out.println(info.getCompany());
  }
 
  /**
  *      
  * @param is
  */
  private void closeStream(InputStream is) {
   if (is != null) {
     try {
      is.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
  }
 
}
 

 

1.2     HWPFDocument 을 통 해 파일 읽 기
       HWPFDocument 은 현재 Word 문서 의 대표 로 WordExtractor 보다 기능 이 강 합 니 다.이 를 통 해 우 리 는 문서 의 표,목록 등 을 읽 을 수 있 고 문서 의 내용 을 추가,수정,삭제 할 수 있 습 니 다.다만 이러한 추가,수정,삭 제 를 마 친 후 관련 정 보 는 HWPFDocument 에 저 장 된 것 으로,디스크 에 있 는 파일 이 아 닌 HWPFDocument 을 변경 한 것 이다.이 수정 사항 을 적용 하려 면 HWPFDocument 의 write 방법 으로 수 정 된 HWPFDocument 을 지정 한 출력 흐름 에 출력 할 수 있 습 니 다.이것 은 원본 파일 의 출력 흐름 일 수도 있 고,새 파일 의 출력 흐름 일 수도 있 으 며,다른 출력 흐름 일 수도 있 습 니 다.다음은 HWPFDocument 을 통 해 파일 을 읽 는 예제 입 니 다.

public class HwpfTest {
 
  @Test
  public void testReadByDoc() throws Exception {
   InputStream is = new FileInputStream("D:\\test.doc");
   HWPFDocument doc = new HWPFDocument(is);
   //      
   this.printInfo(doc.getBookmarks());
   //    
   System.out.println(doc.getDocumentText());
   Range range = doc.getRange();
//  this.insertInfo(range);
   this.printInfo(range);
   //   
   this.readTable(range);
   //   
   this.readList(range);
   //  range
   Range r = new Range(2, 5, doc);
   r.delete();//        ,                   
   //   HWPFDocument      
   doc.write(new FileOutputStream("D:\\test.doc"));
   this.closeStream(is);
  }
 
  /**
  *      
  * @param is
  */
  private void closeStream(InputStream is) {
   if (is != null) {
     try {
      is.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
  }
 
  /**
  *       
  * @param bookmarks
  */
  private void printInfo(Bookmarks bookmarks) {
   int count = bookmarks.getBookmarksCount();
   System.out.println("    :" + count);
   Bookmark bookmark;
   for (int i=0; i<count; i++) {
     bookmark = bookmarks.getBookmark(i);
     System.out.println("  " + (i+1) + "    :" + bookmark.getName());
     System.out.println("    :" + bookmark.getStart());
     System.out.println("    :" + bookmark.getEnd());
   }
  }
 
  /**
  *    
  *             ,        ,              ,          。
  * @param range
  */
  private void readTable(Range range) {
   //  range    table。
   TableIterator tableIter = new TableIterator(range);
   Table table;
   TableRow row;
   TableCell cell;
   while (tableIter.hasNext()) {
     table = tableIter.next();
     int rowNum = table.numRows();
     for (int j=0; j<rowNum; j++) {
      row = table.getRow(j);
      int cellNum = row.numCells();
      for (int k=0; k<cellNum; k++) {
        cell = row.getCell(k);
        //        
        System.out.println(cell.text().trim());
      }
     }
   }
  }
 
  /**
  *    
  * @param range
  */
  private void readList(Range range) {
   int num = range.numParagraphs();
   Paragraph para;
   for (int i=0; i<num; i++) {
     para = range.getParagraph(i);
     if (para.isInList()) {
      System.out.println("list: " + para.text());
     }
   }
  }
 
  /**
  *   Range
  * @param range
  */
  private void printInfo(Range range) {
   //     
   int paraNum = range.numParagraphs();
   System.out.println(paraNum);
   for (int i=0; i<paraNum; i++) {
//    this.insertInfo(range.getParagraph(i));
     System.out.println("  " + (i+1) + ":" + range.getParagraph(i).text());
     if (i == (paraNum-1)) {
      this.insertInfo(range.getParagraph(i));
     }
   }
   int secNum = range.numSections();
   System.out.println(secNum);
   Section section;
   for (int i=0; i<secNum; i++) {
     section = range.getSection(i);
     System.out.println(section.getMarginLeft());
     System.out.println(section.getMarginRight());
     System.out.println(section.getMarginTop());
     System.out.println(section.getMarginBottom());
     System.out.println(section.getPageHeight());
     System.out.println(section.text());
   }
  }
 
  /**
  *      Range,         
  * @param range
  */
  private void insertInfo(Range range) {
   range.insertAfter("Hello");
  }
 
}
2       워드 doc 파일 쓰기
       POI 를 사용 하여 워드 doc 파일 을 쓸 때 우 리 는 먼저 doc 파일 이 있어 야 합 니 다.왜냐하면 우 리 는 doc 파일 을 쓸 때 HWPFDocument 을 통 해 썼 고 HWPFDocument 은 doc 파일 에 의존 해 야 하기 때 문 입 니 다.그래서 일반적인 방법 은 하 드 디스크 에 빈 내용 의 doc 파일 을 준비 한 다음 에 이 빈 파일 을 기반 으로 하 는 HWPFDocument 을 만 드 는 것 입 니 다.그 후에 우 리 는 HWPFDocument 에 내용 을 추가 한 후에 그것 을 다른 doc 파일 에 기록 할 수 있 습 니 다.그러면 우리 가 POI 를 사용 하여 워드 doc 파일 을 만 든 것 과 같 습 니 다.
       실제 응용 프로그램 에서 우 리 는 워드 파일 을 만 들 때 특정한 파일 을 만 듭 니 다.이 파일 의 형식 은 고정 되 어 있 습 니 다.다만 일부 필드 가 다 를 뿐 입 니 다.그래서 실제 응용 에서 우 리 는 전체 워드 파일 의 내용 이 HWPFDocument 을 통 해 생 성 되 지 않 아 도 됩 니 다.디스크 에 워드 문 서 를 새로 만 드 는 것 입 니 다.그 내용 은 우리 가 생 성 해 야 할 워드 파일 의 내용 입 니 다.그 다음 에 변수 에 속 하 는 내용 을'${paramName}'과 같은 방식 으로 대체 합 니 다.이렇게 하면 우 리 는 특정한 정 보 를 바탕 으로 워드 파일 을 만 들 때 이 워드 파일 을 기반 으로 하 는 HWPFDocument 을 가 져 온 다음 Range 의 replace Text()방법 으로 해당 하 는 변 수 를 대응 하 는 값 으로 바 꾸 면 됩 니 다.그 다음 에 현재 HWPFDocument 을 새로운 전송 흐름 에 기록 합 니 다.이런 방식 은 실제 응용 에서 비교적 많이 사용 된다.왜냐하면 그것 은 우리 의 작업량 을 줄 일 수 있 을 뿐만 아니 라 텍스트 의 형식 도 더욱 명확 하 게 할 수 있 기 때문이다.다음 에 우 리 는 이런 방식 에 근거 하여 예 를 들 어 보 겠 다.
       만약 에 우리 가 현재 변 경 된 정 보 를 가지 고 있다 고 가정 한 다음 에 이 정 보 를 통 해 다음 과 같은 형식의 워드 doc 파일 을 생 성 해 야 합 니 다.
 
        그러면 위의 설명 에 따라 먼저 첫 번 째 단 계 는 해당 하 는 형식의 doc 파일 을 템 플 릿 으로 만 듭 니 다.그 내용 은 다음 과 같 습 니 다.
 
        이러한 템 플 릿 이 있 으 면 우 리 는 대응 하 는 HWPFDocument 을 만 든 다음 에 대응 하 는 변 수 를 해당 하 는 값 으로 바 꾸 고 HWPFDocument 을 해당 하 는 출력 흐름 으로 출력 하면 됩 니 다.다음은 대응 하 는 코드 입 니 다.

public class HwpfTest {
 
  @Test
  public void testWrite() throws Exception {
   String templatePath = "D:\\word\\template.doc";
   InputStream is = new FileInputStream(templatePath);
   HWPFDocument doc = new HWPFDocument(is);
   Range range = doc.getRange();
   // range    ${reportDate}        
   range.replaceText("${reportDate}", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
   range.replaceText("${appleAmt}", "100.00");
   range.replaceText("${bananaAmt}", "200.00");
   range.replaceText("${totalAmt}", "300.00");
   OutputStream os = new FileOutputStream("D:\\word\\write.doc");
   // doc       
   doc.write(os);
   this.closeStream(os);
   this.closeStream(is);
  }
 
  /**
  *      
  * @param is
  */
  private void closeStream(InputStream is) {
   if (is != null) {
     try {
      is.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
  }
 
  /**
  *      
  * @param os
  */
  private void closeStream(OutputStream os) {
   if (os != null) {
     try {
      os.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
  }
 
 
}
 

(주:본 고 는 poi 3.9 를 바탕 으로 쓴 것 이다)
 읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기