Чтение содержимого файла.doc и запись в файл pdf в java
Я пишу Java-код, который использует Apache-poi для чтения.doc-файла ms-office и API-интерфейсов itext jar для создания и записи в pdf-файл. Я сделал чтение текстов и таблиц, напечатанных в файле.doc. Теперь я ищу решение, которое читает изображения, написанные в документе. Я закодировал следующее, чтобы прочитать изображения в файле документа. Почему этот код не работает.
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(run)) не удовлетворяет, но документ имеет изображение JPEG.
Я получаю следующее исключение при чтении таблицы.
java.lang.IllegalArgumentException: этот абзац не первый в таблице в org.apache.poi.hwpf.usermodel.Range.getTable(Range.java:876) в pagecode.ReadDocxOrDocFile.main(ReadDocxOrDocFile.java:11).
Кто-нибудь может помочь мне решить проблему. Спасибо.
1 ответ
Что касается вашего исключения:
Ваш код перебирает все абзацы и вызовы isInTable()
для каждого из них. Поскольку таблицы обычно состоят из нескольких таких абзацев, ваш призыв к getTable()
также выполняется несколько раз для одной таблицы.
Однако вместо этого ваш код должен найти первый абзац таблицы, а затем обработать все абзацы в ней (через getRow(m).getCell(n)
) и в конечном итоге продолжим работу с внешним циклом в первом абзаце после таблицы. В коде это может выглядеть примерно так (при условии, что нет объединенных ячеек, нет вложенных таблиц и других забавных краевых случаев):
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 работают только в том случае, если изображение не встроено в поле (что на самом деле довольно редко). Для полевых изображений (т. Е. Предварительных изображений встроенных OLE) вы должны сделать что-то вроде следующего (непроверенного!):
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()
смотрите здесь.