2013-06-06 42 views
0

我正在寫一個Java代碼,利用Apache-poi來讀取ms-office .doc文件和itext jar API來創建和寫入pdf文件。我已經讀完了在.doc文件中打印的文本和表格。現在我正在尋找一種讀取文檔中寫入的圖像的解決方案。我已經編碼如下來閱讀文檔文件中的圖像。爲什麼這段代碼不工作。閱讀.doc文件的內容,並寫入到pdf文件中的java

public static void main(String[] args) { 
    POIFSFileSystem fs = null; 
    Document document = new Document(); 
    WordExtractor extractor = null ; 
    try { 
     fs = new POIFSFileSystem(new FileInputStream("C:\\DATASTORE\\tableandImage.doc")); 
     HWPFDocument hdocument=new HWPFDocument(fs); 
     extractor = new WordExtractor(hdocument); 
     OutputStream fileOutput = new FileOutputStream(new File("C:/DATASTORE/tableandImage.pdf")); 
     PdfWriter.getInstance(document, fileOutput); 
     document.open(); 
     Range range=hdocument.getRange(); 
     String readText=null; 
     PdfPTable createTable; 
     CharacterRun run; 
     PicturesTable picture; 

     for(int i=0;i<range.numParagraphs();i++) { 
      Paragraph par = range.getParagraph(i); 
      readText=par.text(); 
      if(!par.isInTable()) { 
       if(readText.endsWith("\n")) { 
        readText=readText+"\n"; 
        document.add(new com.itextpdf.text.Paragraph(readText)); 
       } if(readText.endsWith("\r")) { 
         readText += "\n"; 
         document.add(new com.itextpdf.text.Paragraph(readText)); 
        } 
       run =range.getCharacterRun(i); 
       picture=hdocument.getPicturesTable(); 
       if(picture.hasPicture(run)) { 
       //if(run.isSpecialCharacter()) { 
        Picture pic=picture.extractPicture(run, true); 
        byte[] picturearray=pic.getContent(); 
        com.itextpdf.text.Image image=com.itextpdf.text.Image.getInstance(picturearray); 
        document.add(image); 
       } 
      } else if (par.isInTable()) { 
        Table table = range.getTable(par); 
        TableRow tRow1= table.getRow(0); 
        int numColumns=tRow1.numCells(); 
        createTable=new PdfPTable(numColumns); 
        for (int rowId=0;rowId<table.numRows();rowId++) { 
         TableRow tRow = table.getRow(rowId); 
         for (int cellId=0;cellId<tRow.numCells();cellId++) { 
          TableCell tCell = tRow.getCell(cellId); 
          PdfPCell c1 = new PdfPCell(new Phrase(tCell.text())); 
          createTable.addCell(c1); 
         } 
        } 
        document.add(createTable); 
       } 
     } 
    }catch(IOException e) { 
     System.out.println("IO Exception"); 
     e.printStackTrace(); 
    } 
    catch(Exception exep) { 
     exep.printStackTrace(); 
    }finally { 
     document.close(); 
    } 
} 

的問題是:1。 如果條件(picture.hasPicture(運行))不令人滿意,但文件有JPEG圖像。

  1. 我在閱讀表時遇到以下異常。

    java.lang.IllegalArgumentException異常:此段不在org.apache.poi.hwpf.usermodel.Range.getTable(Range.java:876)表 第一個 在pagecode.ReadDocxOrDocFile.main( ReadDocxOrDocFile.java:113)

任何人都可以幫助我解決問題。 謝謝。

回答

0

關於你提到的例外:在所有段落

你的代碼循環,並呼籲isInTable()對於他們中的每一個。由於表格通常由幾個這樣的段落組成,您對getTable()的調用也會針對單個表格執行多次。

但是,您的代碼應該做的是找到表的第一段,然後處理其中的所有段落(通過getRow(m).getCell(n)),並最終在表之後的第一段中繼續外循環。 Codewise這可能看起來大致類似如下(假設沒有合併的單元格,沒有嵌套表,沒有其他有趣的邊緣情況):

if (par.isInTable()) { 
    Table table = range.getTable(par); 
    for (int rn=0; rn<table.numRows(); rn++) { 
     TableRow row = table.getRow(rn); 
     for (int cn=0; cn<row.numCells(); cn++) { 
      TableCell cell = row.getCell(cn); 
      for (int pn=0; pn<cell.numParagraphs(); pn++) { 
       Paragraph cellParagraph = cell.getParagraph(pn); 
       // your PDF conversion code goes here 
      } 
     } 
    } 
    i += table.numParagraphs()-1; // skip the already processed (table-)paragraphs in the outer loop 
} 

關於照片的問題:

難道我猜對的,你是試圖獲得固定在給定段落內的圖片?不幸的是,POI的預定義方法只有在圖片未嵌入字段(實際上很少見)的情況下才起作用。對於基於現場的圖像(即嵌入OLES的預覽圖像),你應該這樣做以下(未經測試!):

PictureStore pictureStore = new PictureStore(hdocument); 
// bla bla ... 
for (int cr=0; cr < par.numCharacterRuns(); cr++) { 
    CharacterRun characterRun = par.getCharacterRun(cr); 
    Field field = hdocument.getFields().getFieldByStartOffset(FieldsDocumentPart.MAIN, characterRun.getStartOffset()); 
    if (field != null && field.getType() == 0x3A) { // 0x3A is type "EMBED" 
     Picture pic = pictureStore.getPicture(field.secondSubrange(characterRun)); 
    } 
} 

對於Field.getType()可能值的列表,請參閱here