Android中怎么讀寫PDF文件

這篇文章將為大家詳細(xì)講解有關(guān)Android中怎么讀寫PDF文件,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

成都服務(wù)器托管,成都創(chuàng)新互聯(lián)公司提供包括服務(wù)器租用、綿陽(yáng)主機(jī)托管、帶寬租用、云主機(jī)、機(jī)柜租用、主機(jī)租用托管、CDN網(wǎng)站加速、域名申請(qǐng)等業(yè)務(wù)的一體化完整服務(wù)。電話咨詢:18980820575

一、在Android Studio中如何用POI組件

從POI官網(wǎng)上看,貌似暫并不支持IntelliJ IDE,如下圖,所以這里我們采用直接下載jar包并導(dǎo)入項(xiàng)目的方式。

Android中怎么讀寫PDF文件

通過(guò) 官網(wǎng) ->Overview->Components,可以看到 d和docx文件分別對(duì)應(yīng)著組件 HWPF 和XWPF  ,而HWPF和XWPF則對(duì)應(yīng)著poi-scratchpad和poi-ooxml

Android中怎么讀寫PDF文件 

Android中怎么讀寫PDF文件

下載

進(jìn)入Apache 下載頁(yè)面 ,選擇***版下載,如下。選擇The latest beta release is Apache POI  3.16-beta2會(huì)跳轉(zhuǎn)到poi-bin-3.16-beta2-20170202.tar.gz,然后點(diǎn)擊poi-bin-3.16-beta2-20170202.tar.gz,選擇鏡像后即可成功下載。

注linux系統(tǒng)選擇.tar.gz windows系統(tǒng)選擇.zip

Android中怎么讀寫PDF文件

解壓

將下載后的壓縮包解壓,會(huì)得到以下文件。

Android中怎么讀寫PDF文件 

Android中怎么讀寫PDF文件

導(dǎo)入

不熟悉怎么導(dǎo)入的同學(xué)可以看看 Android Studio導(dǎo)入jar包教程

1、doc 對(duì)于doc文件,需要將  lib文件夾下jar包,poi-3.16-beta2.jar,poi-scratchpad-3.16-beta2.jar  放入android項(xiàng)目libs目錄下(lib文件夾下的junit-4.12.jar和log4j-1.2.17.jar不放我的項(xiàng)目也沒出現(xiàn)異常,能少點(diǎn)是點(diǎn))。

Android中怎么讀寫PDF文件

2、docx 對(duì)于docx,需要導(dǎo)入  lib文件夾下jar包,poi-3.16-beta2.jar,poi-ooxml-3.16-beta2.jar,poi-ooxml-schemas-3.16-beta2.jar和ooxml-lib下的包  ,由于一直我這一直出現(xiàn) Warning:Ingoring InnerClasses attribute for an anonymous inner class  的錯(cuò)誤,同時(shí)由于doc基本滿足我的需求以及導(dǎo)入這么多jar導(dǎo)致apk體積增大,就沒有去實(shí)現(xiàn)。 有興趣的同學(xué)可以研究研究。

二、實(shí)現(xiàn)doc文件的讀寫

Apache POI中的HWPF模塊是專門用來(lái)讀取和生成doc格式的文件。在HWPF中,我們使用HWPFDocument來(lái)表示一個(gè)word  doc文檔。在看代碼之前,有必要了解HWPFDocument中的幾個(gè)概念:

Android中怎么讀寫PDF文件

注意 : Section、Paragraph、CharacterRun和Table都繼承自Range。

讀寫前注意: Apache POI 提供的HWPFDocument類只能讀寫規(guī)范的.doc文件,也就是說(shuō)假如你使用修改 后綴名  的方式生成doc文件或者直接以命名的方式創(chuàng)建,將會(huì)出現(xiàn)錯(cuò)誤“Your file appears not to be a valid OLE2  document”

Invalid header signature; read 0x7267617266202E31, expected  0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document

DOC讀

讀doc文件有兩種方式 (a)通過(guò)WordExtractor讀文件 (b)通過(guò)HWPFDocument讀文件

在日常應(yīng)用中,我們從word文件里面讀取信息的情況非常少見,更多的還是把內(nèi)容寫入到word文件中。使用POI從word  doc文件讀取數(shù)據(jù)時(shí)主要有兩種方式:通過(guò)WordExtractor讀和通過(guò)HWPFDocument讀。在WordExtractor內(nèi)部進(jìn)行信息讀取時(shí)還是通過(guò)HWPFDocument來(lái)獲取的。

使用WordExtractor讀

在使用WordExtractor讀文件時(shí)我們只能讀到文件的文本內(nèi)容和基于文檔的一些屬性,至于文檔內(nèi)容的屬性等是無(wú)法讀到的。如果要讀到文檔內(nèi)容的屬性則需要使用HWPFDocument來(lái)讀取了。下面是使用WordExtractor讀取文件的一個(gè)示例:

//通過(guò)WordExtractor讀文件public class WordExtractorTest {     private final String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "test.doc");   private static final String TAG = "WordExtractorTest";       private void log(Object o) {        Log.d(TAG, String.valueOf(o));    }   public void testReadByExtractor() throws Exception {       InputStream is = new FileInputStream(PATH);       WordExtractor extractor = new WordExtractor(is);      //輸出word文檔所有的文本       log(extractor.getText());       log(extractor.getTextFromPieces());      //輸出頁(yè)眉的內(nèi)容       log("頁(yè)眉:" + extractor.getHeaderText());      //輸出頁(yè)腳的內(nèi)容       log("頁(yè)腳:" + extractor.getFooterText());      //輸出當(dāng)前word文檔的元數(shù)據(jù)信息,包括作者、文檔的修改時(shí)間等。       log(extractor.getMetadataTextExtractor().getText());      //獲取各個(gè)段落的文本       String paraTexts[] = extractor.getParagraphText();      for (int i=0; i<paraTexts.length; i++) {          log("Paragraph " + (i+1) + " : " + paraTexts[i]);       }      //輸出當(dāng)前word的一些信息       printInfo(extractor.getSummaryInformation());      //輸出當(dāng)前word的一些信息       this.printInfo(extractor.getDocSummaryInformation());      this.closeStream(is);    }      /**     * 輸出SummaryInfomation     * @param info     */    private void printInfo(SummaryInformation info) {      //作者       log(info.getAuthor());      //字符統(tǒng)計(jì)       log(info.getCharCount());      //頁(yè)數(shù)       log(info.getPageCount());      //標(biāo)題       log(info.getTitle());      //主題       log(info.getSubject());    }      /**     * 輸出DocumentSummaryInfomation     * @param info     */    private void printInfo(DocumentSummaryInformation info) {      //分類       log(info.getCategory());      //公司       log(info.getCompany());    }      /**     * 關(guān)閉輸入流     * @param is     */    private void closeStream(InputStream is) {      if (is != null) {         try {             is.close();          } catch (IOException e) {             e.printStackTrace();          }       }    }}

使用HWPFDocument讀

HWPFDocument是當(dāng)前Word文檔的代表,它的功能比WordExtractor要強(qiáng)。通過(guò)它我們可以讀取文檔中的表格、列表等,還可以對(duì)文檔的內(nèi)容進(jìn)行新增、修改和刪除操作。只是在進(jìn)行完這些新增、修改和刪除后相關(guān)信息是保存在HWPFDocument中的,也就是說(shuō)我們改變的是HWPFDocument,而不是磁盤上的文件。如果要使這些修改生效的話,我們可以調(diào)用HWPFDocument的write方法把修改后的HWPFDocument輸出到指定的輸出流中。這可以是原文件的輸出流,也可以是新文件的輸出流(相當(dāng)于另存為)或其它輸出流。下面是一個(gè)通過(guò)HWPFDocument讀文件的示例:

//使用HWPFDocument讀文件public class HWPFDocumentTest {       private final String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "test.doc");   private static final String TAG = "HWPFDocumentTest";       private void log(Object o) {        Log.d(TAG, String.valueOf(o));    }   public void testReadByDoc() throws Exception {       InputStream is = new FileInputStream(PATH);       HWPFDocument doc = new HWPFDocument(is);      //輸出書簽信息       this.printInfo(doc.getBookmarks());      //輸出文本       log(doc.getDocumentText());       Range range = doc.getRange();      //讀整體       this.printInfo(range);      //讀表格       this.readTable(range);      //讀列表       this.readList(range);      this.closeStream(is);    }      /**     * 關(guān)閉輸入流     * @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();       log("書簽數(shù)量:" + count);       Bookmark bookmark;      for (int i=0; i<count; i++) {          bookmark = bookmarks.getBookmark(i);          log("書簽" + (i+1) + "的名稱是:" + bookmark.getName());          log("開始位置:" + bookmark.getStart());          log("結(jié)束位置:" + bookmark.getEnd());       }    }      /**     * 讀表格     * 每一個(gè)回車符代表一個(gè)段落,所以對(duì)于表格而言,每一個(gè)單元格至少包含一個(gè)段落,每行結(jié)束都是一個(gè)段落。     * @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);                //輸出單元格的文本                 log(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()) {             log("list: " + para.text());          }       }    }      /**     * 輸出Range     * @param range     */    private void printInfo(Range range) {      //獲取段落數(shù)       int paraNum = range.numParagraphs();       log(paraNum);      for (int i=0; i<paraNum; i++) {          log("段落" + (i+1) + ":" + range.getParagraph(i).text());         if (i == (paraNum-1)) {            this.insertInfo(range.getParagraph(i));          }       }      int secNum = range.numSections();       log(secNum);       Section section;      for (int i=0; i<secNum; i++) {          section = range.getSection(i);          log(section.getMarginLeft());          log(section.getMarginRight());          log(section.getMarginTop());          log(section.getMarginBottom());          log(section.getPageHeight());          log(section.text());       }    }      /**     * 插入內(nèi)容到Range,這里只會(huì)寫到內(nèi)存中     * @param range     */    private void insertInfo(Range range) {       range.insertAfter("Hello");    }}

DOC寫

使用HWPFDocument寫文件

在使用POI寫word  doc文件的時(shí)候我們必須要先有一個(gè)doc文件才行,因?yàn)槲覀冊(cè)趯慸oc文件的時(shí)候是通過(guò)HWPFDocument來(lái)寫的,而HWPFDocument是要依附于一個(gè)doc文件的。所以通常的做法是我們先在硬盤上準(zhǔn)備好一個(gè)內(nèi)容空白的doc文件,然后建立一個(gè)基于該空白文件的HWPFDocument。之后我們就可以往HWPFDocument里面新增內(nèi)容了,然后再把它寫入到另外一個(gè)doc文件中,這樣就相當(dāng)于我們使用POI生成了word  doc文件。

//寫字符串進(jìn)word     InputStream is = new FileInputStream(PATH);     HWPFDocument doc = new HWPFDocument(is);    //獲取Range     Range range = doc.getRange();    for(int i = 0; i < 100; i++) {        if( i % 2 == 0 ) {             range.insertAfter("Hello " + i + "\n");//在文件末尾插入String         } else {             range.insertBefore("      Bye " + i + "\n");//在文件頭插入String         }     }    //寫到原文件中     OutputStream os = new FileOutputStream(PATH);    //寫到另一個(gè)文件中     //OutputStream os = new FileOutputStream(其他路徑);     doc.write(os);    this.closeStream(is);    this.closeStream(os);

但是,在實(shí)際應(yīng)用中,我們?cè)谏蓋ord文件的時(shí)候都是生成某一類文件,該類文件的格式是固定的,只是某些字段不一樣罷了。所以在實(shí)際應(yīng)用中,我們大可不必將整個(gè)word文件的內(nèi)容都通過(guò)HWPFDocument生成。而是先在磁盤上新建一個(gè)word文檔,其內(nèi)容就是我們需要生成的word文件的內(nèi)容,然后把里面一些屬于變量的內(nèi)容使用類似于“${paramName}”這樣的方式代替。這樣我們?cè)诨谀承┬畔⑸蓋ord文件的時(shí)候,只需要獲取基于該word文件的HWPFDocument,然后調(diào)用Range的replaceText()方法把對(duì)應(yīng)的變量替換為對(duì)應(yīng)的值即可,之后再把當(dāng)前的HWPFDocument寫入到新的輸出流中。這種方式在實(shí)際應(yīng)用中用的比較多,因?yàn)樗坏梢詼p少我們的工作量,還可以讓文本的格式更加的清晰。下面我們就來(lái)基于這種方式做一個(gè)示例。

假設(shè)我們有個(gè)模板是這樣的:

Android中怎么讀寫PDF文件

之后我們以該文件作為模板,利用相關(guān)數(shù)據(jù)把里面的變量進(jìn)行替換,然后把替換后的文檔輸出到另一個(gè)doc文件中。具體做法如下:

public class HWPFTemplateTest {    /**     * 用一個(gè)doc文檔作為模板,然后替換其中的內(nèi)容,再寫入目標(biāo)文檔中。     * @throws Exception     */           @Test    public void testTemplateWrite() throws Exception {       String templatePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "template.doc");        String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "target.doc";       InputStream is = new FileInputStream(templatePath);       HWPFDocument doc = new HWPFDocument(is);       Range range = doc.getRange();      //把range范圍內(nèi)的${reportDate}替換為當(dāng)前的日期       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(targetPath);      //把doc輸出到輸出流中       doc.write(os);      this.closeStream(os);      this.closeStream(is);    }      /**     * 關(guān)閉輸入流     * @param is     */    private void closeStream(InputStream is) {      if (is != null) {         try {             is.close();          } catch (IOException e) {             e.printStackTrace();          }       }    }     /**     * 關(guān)閉輸出流     * @param os     */    private void closeStream(OutputStream os) {      if (os != null) {         try {             os.close();          } catch (IOException e) {             e.printStackTrace();          }       }    }}

三、實(shí)現(xiàn)docx文件的讀寫

POI在讀寫word  docx文件時(shí)是通過(guò)xwpf模塊來(lái)進(jìn)行的,其核心是XWPFDocument。一個(gè)XWPFDocument代表一個(gè)docx文檔,其可以用來(lái)讀docx文檔,也可以用來(lái)寫docx文檔。XWPFDocument中主要包含下面這幾種對(duì)象:

Android中怎么讀寫PDF文件

同時(shí)XWPFDocument可以直接new一個(gè)docx文件出來(lái)而不需要像HWPFDocument一樣需要一個(gè)模板存在。

關(guān)于Android中怎么讀寫PDF文件就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)站欄目:Android中怎么讀寫PDF文件
URL標(biāo)題:http://bm7419.com/article0/pcdcio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、全網(wǎng)營(yíng)銷推廣靜態(tài)網(wǎng)站、品牌網(wǎng)站制作、電子商務(wù)外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)