JAVA實現(xiàn)Word文件讀寫

準備材料
1、在D盤下新建一個template.doc文檔,內(nèi)容如下:


image.png

2、pom.xml依賴:

<dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

3、項目結(jié)構(gòu):


image.png

4、概念
Apache poi的hwpf模塊是專門用來對word doc文件進行讀寫操作的。在hwpf里面我們使用HWPFDocument來表示一個word doc文檔。在HWPFDocument里面有這么幾個概念:
Range:它表示一個范圍,這個范圍可以是整個文檔,也可以是里面的某一小節(jié)(Section),也可以是某一個段落(Paragraph),還可以是擁有共同屬性的一段文本(CharacterRun)。
Section:word文檔的一個小節(jié),一個word文檔可以由多個小節(jié)構(gòu)成。
Paragraph:word文檔的一個段落,一個小節(jié)可以由多個段落構(gòu)成。
CharacterRun:具有相同屬性的一段文本,一個段落可以由多個CharacterRun組成。
Table:一個表格。
TableRow:表格對應的行。
TableCell:表格對應的單元格。
Section、Paragraph、CharacterRun和Table都繼承自Range。

讀取Word文件功能
1、讀取文件類ReadDoc.java:

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;

public class ReadDoc {
    public void testReadByDoc(String path) throws Exception {
        InputStream is = new FileInputStream(path);
        HWPFDocument doc = new HWPFDocument(is);
        //輸出書簽信息
        this.printInfo(doc.getBookmarks());
        //輸出文本
        System.out.println(doc.getDocumentText());
        Range range = doc.getRange();
        this.printInfo(range);
        //讀表格
        this.readTable(range);
        //讀列表
        this.readList(range);
        //把當前HWPFDocument寫到輸出流中
        doc.write(new FileOutputStream("D:\\test.doc"));
        is.close();
    }

    /**
     * 輸出書簽信息
     * @param bookmarks
     */
    private void printInfo(Bookmarks bookmarks) {
        int count = bookmarks.getBookmarksCount();
        System.out.println("書簽數(shù)量:" + 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("結(jié)束位置:" + bookmark.getEnd());
        }
    }

    /**
     * 讀表格
     * 每一個回車符代表一個段落,所以對于表格而言,每一個單元格至少包含一個段落,每行結(jié)束都是一個段落。
     * @param range
     */
    private void readTable(Range range) {
        //遍歷range范圍內(nèi)的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) {
        //獲取段落數(shù)
        int paraNum = range.numParagraphs();
        System.out.println(paraNum);
        for (int i=0; i<paraNum; i++) {
            System.out.println("段落" + (i+1) + ":" + range.getParagraph(i).text());
        }
        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());
        }
    }
}

2、功能測試:

import org.junit.Test;

public class ReadDocTest {
    @Test
    public void testReadByDoc() throws Exception {
        ReadDoc rd = new ReadDoc();
        rd.testReadByDoc("D:\\template.doc");
    }
}

寫入文件功能
1、寫入文件類WriteDoc.java:

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class WriteDoc {
    public void testWrite() throws Exception {
        List<Users> list = new ArrayList<Users>();
        list.add(new Users("a","男",10,new SimpleDateFormat("yyyy-MM-dd").parse("2018-08-08")));
        list.add(new Users("b","女",20,new SimpleDateFormat("yyyy-MM-dd").parse("2017-07-07")));

        String templatePath = "D:\\template.doc";
        InputStream is = new FileInputStream(templatePath);
        OutputStream os = null;
        HWPFDocument doc = new HWPFDocument(is);
        Range range = doc.getRange();
        for(int i=0;i<list.size();i++){
            Users user = list.get(i);
            //把range范圍內(nèi)的${reportDate}替換為當前的日期
            range.replaceText("${name}", user.getName());
            range.replaceText("${sex}", user.getSex());
            range.replaceText("${age}", String.valueOf(user.getAge()));
            range.replaceText("${date}", user.getBirthday().toString());
            os = new FileOutputStream(new File("D:\\"+user.getName()+".doc"));
            //把doc輸出到輸出流中
            doc.write(os);
        }
        os.close();
        is.close();
    }
}

2、功能測試:

import org.junit.Test;

public class WriteDocTest {
    @Test
    public void testWrite() throws Exception {
        WriteDoc wd = new WriteDoc();
        wd.testWrite();
    }
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,261評論 6 342
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,638評論 18 399
  • 在討論人工智能這個話題之前,請大家思考兩個問題:一、互聯(lián)網(wǎng)改變了你的生活嗎?二、互聯(lián)網(wǎng)到底有沒有改變你的工作模式/...
    虎說七道閱讀 752評論 0 2

友情鏈接更多精彩內(nèi)容