欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

使用POI讀寫Word doc文件

系統 1809 0

使用 POI 讀寫 word doc 文件

目錄

1???? word doc 文件

1.1???? 通過 WordExtractor 讀文件

1.2???? 通過 HWPFDocument 讀文件

2???? word doc 文件

?

?????? Apache poi hwpf 模塊是專門用來對 word doc 文件進行讀寫操作的。在 hwpf 里面我們使用 HWPFDocument 來表示一個 word doc 文檔。在 HWPFDocument 里面有這么幾個概念:

l ? Range :它表示一個范圍,這個范圍可以是整個文檔,也可以是里面的某一小節( Section ),也可以是某一個段落( Paragraph ),還可以是擁有共同屬性的一段文本( CharacterRun )。

l ? Section word 文檔的一個小節,一個 word 文檔可以由多個小節構成。

l ? Paragraph word 文檔的一個段落,一個小節可以由多個段落構成。

l ? CharacterRun :具有相同屬性的一段文本,一個段落可以由多個 CharacterRun 組成。

l ? Table :一個表格。

l ? TableRow :表格對應的行。

l ? TableCell :表格對應的單元格。

?????? Section Paragraph CharacterRun Table 都繼承自 Range

1 ?????? word doc 文件

?????? 在日常應用中,我們從 word 文件里面讀取信息的情況非常少見,更多的還是把內容寫入到 word 文件中。使用 POI word doc 文件讀取數據時主要有兩種方式:通過 WordExtractor 讀和通過 HWPFDocument 讀。在 WordExtractor 內部進行信息讀取時還是通過 HWPFDocument 來獲取的。

?

1.1 ???? 通過 WordExtractor 讀文件

?????? 在使用 WordExtractor 讀文件時我們只能讀到文件的文本內容和基于文檔的一些屬性,至于文檔內容的屬性等是無法讀到的。如果要讀到文檔內容的屬性則需要使用 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 ?????? word doc 文件

?????? 在使用 POI word doc 文件的時候我們必須要先有一個 doc 文件才行,因為我們在寫 doc 文件的時候是通過 HWPFDocument 來寫的,而 HWPFDocument 是要依附于一個 doc 文件的。所以通常的做法是我們先在硬盤上準備好一個內容空白的 doc 文件,然后建立一個基于該空白文件的 HWPFDocument 。之后我們就可以往 HWPFDocument 里面新增內容了,然后再把它寫入到另外一個 doc 文件中,這樣就相當于我們使用 POI 生成了 word doc 文件。

?????? 在實際應用中,我們在生成 word 文件的時候都是生成某一類文件,該類文件的格式是固定的,只是某些字段不一樣罷了。所以在實際應用中,我們大可不必將整個 word 文件的內容都通過 HWPFDocument 生成。而是先在磁盤上新建一個 word 文檔,其內容就是我們需要生成的 word 文件的內容,然后把里面一些屬于變量的內容使用類似于“ ${paramName} ”這樣的方式代替。這樣我們在基于某些信息生成 word 文件的時候,只需要獲取基于該 word 文件的 HWPFDocument ,然后調用 Range replaceText() 方法把對應的變量替換為對應的值即可,之后再把當前的 HWPFDocument 寫入到新的輸出流中。這種方式在實際應用中用的比較多,因為它不但可以減少我們的工作量,還可以讓文本的格式更加的清晰。下面我們就來基于這種方式做一個示例。

?????? 假設我們現在擁有一些變動的信息,然后需要通過這些信息生成如下格式的 word doc 文件:


使用POI讀寫Word doc文件
?

?????? 那么根據上面的描述,首先第一步,我們建立一個對應格式的 doc 文件作為模板,其內容是這樣的:


使用POI讀寫Word 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();
         }
      }
   }
  
 
}
    

?

(注:本文是基于 poi3.9 所寫)

使用POI讀寫Word doc文件


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日日视频| 天天艹夜夜 | 亚洲一区二区三区深夜天堂 | 色婷亚洲 | 精品美女 | 亚洲高清在线视频 | 91精品国产91久久久久久 | 草草草在线视频 | 丁香花成人另类小说 | 久久一区二区三区不卡 | 亚洲日本在线观看视频 | 日产精品卡二卡三卡四卡乱码视频 | 欧美激情综合色综合啪啪五月 | 成人高清在线观看 | 欧美同性精品xxxx | 三级国产视频 | 午夜看片免费 | 国产精品视频免费视频 | 2018一级毛片免费观看 | 色婷婷视频在线观看 | 国产高清久久久 | v片在线看 | 久久亚洲国产精品 | 日本老熟妇毛茸茸 | 欧美激情精品久久久久久 | 国产在线91精品入口首页 | 无人精品乱码一区二区三区 | 国产99精品一区二区三区免费 | a免费国产一级特黄aa大 | 日韩大片在线永久观看视频网站免费 | 欧美日韩中文一区 | 国产在线网址 | 91精品久久| 成人欧美一区二区三区在线观看 | 韩漫重考生漫画画免费读漫画下拉式土豪漫 | 欧美日韩一区二区三区四区五区 | 成人黄色毛片 | 久久精品 | 伊人精品国产 | 国产片侵犯亲女视频播放 | 中国一级免费视频 |