gpt4 book ai didi

java - 尝试使用 Apache poi 制作简单的 PDF 文档

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:01:26 25 4
gpt4 key购买 nike

我看到互联网上到处都是提示 apache 的 pdf 产品的人,但我在这里找不到我的特定用例。我正在尝试用 apache poi 做一个简单的 Hello World。现在我的代码如下:

public ByteArrayOutputStream export() throws IOException {
//Blank Document
XWPFDocument document = new XWPFDocument();

//Write the Document in file system
ByteArrayOutputStream out = new ByteArrayOutputStream();;

//create table
XWPFTable table = document.createTable();
XWPFStyles styles = document.createStyles();
styles.setSpellingLanguage("English");
//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 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");

PdfOptions options = PdfOptions.create();
PdfConverter.getInstance().convert(document, out, options);
out.close();
return out;
}

调用它的代码是:

    public ResponseEntity<Resource> convertToPDFPost(@ApiParam(value = "DTOs passed from the FE" ,required=true )  @Valid @RequestBody ExportEnvelopeDTO exportDtos) {

if (exportDtos.getProdExportDTOs() != null) {
try {
FileOutputStream out = new FileOutputStream("/Users/kornhaus/Desktop/test.pdf");
out.write(exporter.export().toByteArray());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<Resource>(responseFile, responseHeaders, HttpStatus.OK);
}

return new ResponseEntity<Resource>(HttpStatus.INTERNAL_SERVER_ERROR);
}

}

在此处的这一行:out.write(exporter.export().toByteArray());
代码抛出异常:

org.apache.poi.xwpf.converter.core.XWPFConverterException: java.io.IOException: Unable to parse xml bean

我不知道是什么原因造成的,甚至不知道去哪里寻找此类文档。我已经编写了十多年的代码,并且从来没有遇到过应该是一个简单的 Java 库的困难。任何帮助都会很棒。

最佳答案

主要问题是那些 PdfOptionsPdfConverter 不是 apache poi 项目的一部分。它们由 opensagres 开发,第一个版本被错误地命名为 org.apache.poi.xwpf.converter.pdf.PdfOptionsorg.apache.poi.xwpf。转换器.pdf.PdfConverter。这些旧类自 2014 年以来未更新,需要 apache poi 版本 3.9 才能使用。

但相同的开发人员提供了 fr.opensagres.poi.xwpf.converter.pdf ,这是最新的并且使用最新的稳定版本 apache poi 3.17。所以我们应该使用它。

但由于即使是较新的 PdfOptionsPdfConverter 也不是 apache poi 项目的一部分,apache poi不会用他们的版本测试那些。因此 apache poi 创建的默认 *.docx 文档缺少 PdfConverter 需要的一些内容。

  1. 必须有一个样式文档,即使它是空的。

  2. 至少设置了页面大小的页面必须有部分属性。

  3. 表格必须有表格网格集。

为了实现这一点,我们必须在程序中额外添加一些代码。不幸的是,这需要所有模式的完整 jar ooxml-schemas-1.3.jar,如 Faq-N10025 中所述。 .

并且因为我们需要更改底层低级对象,所以必须编写文档以便提交底层对象。否则我们交给 PdfConverterXWPFDocument 将是不完整的。

例子:

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/xdocreportConverter only with 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();

}
}

2018 年 10 月:此代码使用 apache poi 3.17 运行。它无法使用 apache poi 4.0.0,因为 apache poi 中的更改直到现在才在 fr.opensagres.poi.xwpf.converter 中考虑 以及 fr.opensagres.xdocreport.converter


2019 年 2 月:现在为我工作,使用最新的 apache poi 版本 4.0.1fr.opensagres.poi.xwpf.converter.pdf 的最新版本 2.0.2和配偶。


2021 年 6 月:使用 apache poi 版本 4.1.2fr.opensagres.poi.xwpf.converter.pdf 的最新版本 2.0.2 工作和配偶。无法使用 apache poi 版本 5.0.0 因为 XDocReport 需要 ooxml-schemas which apache poi 5 不再支持。


2022 年 4 月:使用 apache poi 版本 5.2.2fr.opensagres.poi.xwpf.converter.pdf 的最新版本 2.0.3 工作和配偶。

关于java - 尝试使用 Apache poi 制作简单的 PDF 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51330192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com