2013-06-06 45 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