Попытка сделать простой PDF-документ с помощью Apache poi

Это точно правильно, потому что компилятор должен знать, какой тип он предназначен для распределения. Поэтому классы шаблонов, функции, перечисления и т. Д. Должны быть реализованы также в файле заголовка, если он должен быть опубликован или частично из библиотеки (статический или динамический), поскольку файлы заголовков НЕ скомпилированы в отличие от файлов c / cpp, которые находятся. Если компилятор не знает, что тип не может его скомпилировать. В .Net это возможно, потому что все объекты происходят из класса Object. Это не .Net.

2
задан Alex Kornhauser 13 July 2018 в 17:39
поделиться

1 ответ

Основная проблема заключается в том, что те PdfOptions и PdfConverter не являются частью проекта apache poi. Они разработаны opensagres, а первые версии плохо названы org.apache.poi.xwpf.converter.pdf.PdfOptions и org.apache.poi.xwpf.converter.pdf.PdfConverter. Эти старые классы не обновлялись с 2014 года и нуждаются в версии 3.9 из apache poi.

Но те же разработчики предоставляют fr.opensagres.poi.xwpf.converter.pdf , который намного больше тока и работает с использованием последней стабильной версии apache poi 3.17. Поэтому мы должны использовать это.

Но так как даже те, кто PdfOptions и PdfConverter не являются частью проекта apache poi, apache poi не будут тестировать тех, у кого есть их выпуски. И поэтому для документов по умолчанию *.docx, созданных apache poi, не хватает содержимого, которое требуется PdfConverter.

  1. Должен быть документ стилей, даже если он пуст.
  2. Должны быть свойства раздела для страницы, имеющей, по крайней мере, размер страницы.
  3. Таблицы должны иметь набор сетки таблицы.

Чтобы выполнить это, мы должны добавить дополнительный код в нашу программу. К сожалению, для этого требуется полная фляга всех схем ooxml-schemas-1.3.jar, как указано в Faq-N10025 .

И поскольку нам нужно изменить подстилающие объекты низкого уровня, документ должен быть написаны, так что подстилающие объекты будут совершены. Еще XWPFDocument, который мы передаем PdfConverter, будет неполным.

Пример:

import java.io.*;
import java.math.BigInteger;

//needed jars: fr.opensagres.poi.xwpf.converter.core-2.0.1.jar, 
//             fr.opensagres.poi.xwpf.converter.pdf-2.0.1.jar,
//             fr.opensagres.xdocreport.itext.extension-2.0.1.jar,
//             itext-2.1.7.jar                                  
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;

//needed jars: apache poi and it's dependencies
//             and additionally: ooxml-schemas-1.3.jar 
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

public class XWPFToPDFConverterSampleMin {

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  // there must be a styles document, even if it is empty
  XWPFStyles styles = document.createStyles();

  // there must be section properties for the page having at least the page size set
  CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
  CTPageSz pageSz = sectPr.addNewPgSz();
  pageSz.setW(BigInteger.valueOf(12240)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
  pageSz.setH(BigInteger.valueOf(15840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"

  // filling the body
  XWPFParagraph paragraph = document.createParagraph();

  //create table
  XWPFTable table = document.createTable();

  //create first row
  XWPFTableRow tableRowOne = table.getRow(0);
  tableRowOne.getCell(0).setText("col one, row one");
  tableRowOne.addNewTableCell().setText("col two, row one");
  tableRowOne.addNewTableCell().setText("col three, row one");

  //create CTTblGrid for this table with widths of the 3 columns. 
  //necessary for Libreoffice/Openoffice and PdfConverter to accept the column widths.
  //values are in unit twentieths of a point (1/1440 of an inch)
  //first column = 2 inches width
  table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  //other columns (2 in this case) also each 2 inches width
  for (int col = 1 ; col < 3; col++) {
   table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  }

  //create second row
  XWPFTableRow tableRowTwo = table.createRow();
  tableRowTwo.getCell(0).setText("col one, row two");
  tableRowTwo.getCell(1).setText("col two, row two");
  tableRowTwo.getCell(2).setText("col three, row two");

  //create third row
  XWPFTableRow tableRowThree = table.createRow();
  tableRowThree.getCell(0).setText("col one, row three");
  tableRowThree.getCell(1).setText("col two, row three");
  tableRowThree.getCell(2).setText("col three, row three");

  paragraph = document.createParagraph();

  //trying picture
  XWPFRun run = paragraph.createRun();
  run.setText("The picture in line: ");
  InputStream in = new FileInputStream("samplePict.jpeg");
  run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(30));
  in.close();  
  run.setText(" text after the picture.");

  paragraph = document.createParagraph();

  //document must be written so underlaaying objects will be committed
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  document.write(out);
  document.close();

  document = new XWPFDocument(new ByteArrayInputStream(out.toByteArray()));
  PdfOptions options = PdfOptions.create();
  PdfConverter converter = (PdfConverter)PdfConverter.getInstance();
  converter.convert(document, new FileOutputStream("XWPFToPDFConverterSampleMin.pdf"), options);

  document.close();

 }
}

Использование XDocReport

Другой способ будет использовать новейшую версию opensagres / xdocreport , как описано в Converter, только с ConverterRegistry :

import java.io.*;
import java.math.BigInteger;

//needed jars: xdocreport-2.0.1.jar, 
//             odfdom-java-0.8.7.jar,
//             itext-2.1.7.jar  
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.converter.IConverter;
import fr.opensagres.xdocreport.converter.ConverterRegistry;
import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.core.document.DocumentKind;

//needed jars: apache poi and it's dependencies
//             and additionally: ooxml-schemas-1.3.jar 
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

public class XWPFToPDFXDocReport {

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  // there must be a styles document, even if it is empty
  XWPFStyles styles = document.createStyles();

  // there must be section properties for the page having at least the page size set
  CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
  CTPageSz pageSz = sectPr.addNewPgSz();
  pageSz.setW(BigInteger.valueOf(12240)); //12240 Twips = 12240/20 = 612 pt = 612/72 = 8.5"
  pageSz.setH(BigInteger.valueOf(15840)); //15840 Twips = 15840/20 = 792 pt = 792/72 = 11"

  // filling the body
  XWPFParagraph paragraph = document.createParagraph();

  //create table
  XWPFTable table = document.createTable();

  //create first row
  XWPFTableRow tableRowOne = table.getRow(0);
  tableRowOne.getCell(0).setText("col one, row one");
  tableRowOne.addNewTableCell().setText("col two, row one");
  tableRowOne.addNewTableCell().setText("col three, row one");

  //create CTTblGrid for this table with widths of the 3 columns. 
  //necessary for Libreoffice/Openoffice and PdfConverter to accept the column widths.
  //values are in unit twentieths of a point (1/1440 of an inch)
  //first column = 2 inches width
  table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  //other columns (2 in this case) also each 2 inches width
  for (int col = 1 ; col < 3; col++) {
   table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(2*1440));
  }

  //create second row
  XWPFTableRow tableRowTwo = table.createRow();
  tableRowTwo.getCell(0).setText("col one, row two");
  tableRowTwo.getCell(1).setText("col two, row two");
  tableRowTwo.getCell(2).setText("col three, row two");

  //create third row
  XWPFTableRow tableRowThree = table.createRow();
  tableRowThree.getCell(0).setText("col one, row three");
  tableRowThree.getCell(1).setText("col two, row three");
  tableRowThree.getCell(2).setText("col three, row three");

  paragraph = document.createParagraph();

  //trying picture
  XWPFRun run = paragraph.createRun();
  run.setText("The picture in line: ");
  InputStream in = new FileInputStream("samplePict.jpeg");
  run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(30));
  in.close();  
  run.setText(" text after the picture.");

  paragraph = document.createParagraph();

  //document must be written so underlaaying objects will be committed
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  document.write(out);
  document.close();

  // 1) Create options DOCX 2 PDF to select well converter form the registry
  Options options = Options.getFrom(DocumentKind.DOCX).to(ConverterTypeTo.PDF);

  // 2) Get the converter from the registry
  IConverter converter = ConverterRegistry.getRegistry().getConverter(options);

  // 3) Convert DOCX 2 PDF
  InputStream docxin= new ByteArrayInputStream(out.toByteArray());
  OutputStream pdfout = new FileOutputStream(new File("XWPFToPDFXDocReport.pdf"));
  converter.convert(docxin, pdfout, options);

  docxin.close();       
  pdfout.close();       

 }
}
2
ответ дан Axel Richter 17 August 2018 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: