gpt4 book ai didi

java - 如何将 XML 输出保存为 PDF

转载 作者:行者123 更新时间:2023-12-02 02:12:31 26 4
gpt4 key购买 nike

我正在使用 JAXB 来解码 XML。然后我想获取一些信息并使用 iText 将其写入 PDF 格式。由于某种原因,PDF 已创建,但我无法打开该文件。我还使用 ZFile,因为这也应该适用于大型机,但这在这里不应该成为问题。

可能我在写入 PDF 文件时做错了什么。这是我的代码:

package music;

import java.io.*;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import com.ibm.jzos.ZFile;

import java.io.FileOutputStream;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import music.Music.Artist;
import music.Music.Artist.Album;
import music.Music.Artist.Album.Description;
import music.Music.Artist.Album.Song;

public class MusicXml {

public static void main(String[] args) throws JAXBException, IOException {

ZFile inputZ = null, outputZ = null;

File inputW = null;
PdfWriter outputW = null;

PdfContentByte cb = null;
Document pdf = new Document(PageSize.A4);
Paragraph paragraf = new Paragraph();

// Font
Font fnt12n;

JAXBContext jaxb = null;
Unmarshaller unmarsh = null;

String line = null, sep = " ";
Music music;

Date date = new Date();
Date startDate = new Timestamp(date.getTime());
System.out.println("Start: " + startDate);

jaxb = JAXBContext.newInstance(ObjectFactory.class);
unmarsh = jaxb.createUnmarshaller();

String os = System.getProperty("os.name");
System.out.println("System: " + os);
boolean isWin = os.toLowerCase().contains("wind");

if (!isWin) {
// z/OS:
inputZ = new ZFile(args[0], "rt"); // "rt" - readtext
InputStream inpStream = inputZ.getInputStream();
InputStreamReader streamRdr = new InputStreamReader(inpStream, "CP870");
try {
outputW = PdfWriter.getInstance(pdf, (new ZFile(args[1], "wb")).getOutputStream());
} catch (DocumentException e) {
e.printStackTrace();
}

music = (Music) unmarsh.unmarshal(streamRdr);

} else {
// Windows:
inputW = new File(args[0]);
music = (Music) unmarsh.unmarshal(inputW);
try {
outputW = PdfWriter.getInstance(pdf, new FileOutputStream(args[1]));
} catch (DocumentException e) {
e.printStackTrace();
}
}

List<Artist> listaArtystow = music.getArtist();
for (Artist artysta : listaArtystow) {
List<Album> listaAlbumow = artysta.getAlbum();
for (Album album : listaAlbumow) {
Description opis = album.getDescription();
List<Song> listaPiosenek = album.getSong();
for (Song piosenka : listaPiosenek) {
String artistName = artysta.getName();
String albumName = album.getTitle();
int numberOfSongs = listaPiosenek.size();
String albumDescription = album.getDescription().getValue();
String songTitle = piosenka.getTitle();
String songDuration = piosenka.getLength();

line = songTitle + sep + songDuration;

FontFactory.register(args[2], "jakiesFonty");
Font font = FontFactory.getFont("jakiesFonty", BaseFont.CP1250, BaseFont.EMBEDDED);
BaseFont bf = font.getBaseFont();
fnt12n = new Font(bf, 12f, Font.NORMAL, BaseColor.BLACK);

// PDF
outputW.setPdfVersion(PdfWriter.VERSION_1_7);

pdf.addTitle("Musical collection");
pdf.addAuthor("Natalia Nazaruk");
pdf.addSubject("Cwiczenie tworzenia PDF z XML");
pdf.addKeywords("Metadata, Java, iText, PDF");
pdf.addCreator("Program: MusicXML");
pdf.setMargins(60, 60, 50, 40);

pdf.open();
pdf.newPage();
try {


paragraf.setAlignment(Element.ALIGN_JUSTIFIED);

paragraf.setSpacingAfter(16f);

paragraf.setLeading(14f);

paragraf.setFirstLineIndent(30f);

paragraf.setFont(fnt12n);

pdf.add(new Paragraph(line, fnt12n));


} catch (DocumentException e) {
e.printStackTrace();
}
}
}
}

date = new Date();
Date stopDate = new Timestamp(date.getTime());
System.out.println("Stop: " + stopDate);
long diffInMs = stopDate.getTime() - startDate.getTime();
float diffInSec = diffInMs / 1000.00f;
System.out.format("Czas przetwarzenia pliku XML: %.2f s.", diffInSec);
System.exit(0);

if (isWin) {
outputW.close();
} else
outputZ.close();
}
}

最佳答案

除了您选择使用旧版本的 iText 之外,您的代码还存在其他一些问题。您阅读了哪些文档?我认为您还没有发现 iText 官方网站,否则您会使用 iText 7 而不是 iText 5,并且您会知道如果您从未关闭Document,则不会创建有效文档。对象。

简短的回答是你忘记了:

pdf.close();

我看到您关闭了输出流:

if (isWin) {
outputW.close();
} else
outputZ.close();
}

这实际上没有意义,因为此时 PDF 尚未最终确定(例如:没有创建交叉引用表)。当您关闭文档时,底层输出流将隐式关闭(除非您明确告诉 iText 不要这样做)。

您创建的循环也有一些尴尬的地方:

List<Artist> listaArtystow = music.getArtist();
for (Artist artysta : listaArtystow) {
...
for (Album album : listaAlbumow) {
...
for (Song piosenka : listaPiosenek) {
...
FontFactory.register(args[2], "jakiesFonty");
Font font = FontFactory.getFont("jakiesFonty", BaseFont.CP1250, BaseFont.EMBEDDED);
BaseFont bf = font.getBaseFont();
fnt12n = new Font(bf, 12f, Font.NORMAL, BaseColor.BLACK);
// PDF
outputW.setPdfVersion(PdfWriter.VERSION_1_7);
pdf.addTitle("Musical collection");
pdf.addAuthor("Natalia Nazaruk");
pdf.addSubject("Cwiczenie tworzenia PDF z XML");
pdf.addKeywords("Metadata, Java, iText, PDF");
pdf.addCreator("Program: MusicXML");
pdf.setMargins(60, 60, 50, 40);
pdf.open();
pdf.newPage();
...
}
}
}
output.close();

您一遍又一遍地创建相同的字体。一个 PDF 只能有 1 个版本(在您的情况下为 PDF-1.7)和 1 组元数据,但您却一遍又一遍地定义该版本和元数据。最后,您可以多次打开文档,而只需打开一次。

这更有意义:

FontFactory.register(args[2], "jakiesFonty");
Font font = FontFactory.getFont("jakiesFonty", BaseFont.CP1250, BaseFont.EMBEDDED);
BaseFont bf = font.getBaseFont();
fnt12n = new Font(bf, 12f, Font.NORMAL, BaseColor.BLACK);
// PDF
outputW.setPdfVersion(PdfWriter.VERSION_1_7);
pdf.addTitle("Musical collection");
pdf.addAuthor("Natalia Nazaruk");
pdf.addSubject("Cwiczenie tworzenia PDF z XML");
pdf.addKeywords("Metadata, Java, iText, PDF");
pdf.addCreator("Program: MusicXML");
pdf.setMargins(60, 60, 50, 40);
pdf.open();
List<Artist> listaArtystow = music.getArtist();
for (Artist artysta : listaArtystow) {
...
for (Album album : listaAlbumow) {
...
for (Song piosenka : listaPiosenek) {
...
pdf.newPage();
...
}
}
}
pdf.close();

如您所见,您open() Document实例pdf 循环之前,编写 PDF 标题,然后您close() Document 循环写入一些对象(例如字体)、交叉引用表和 PDF 预告片。因为你没有pdf.close()在您的代码中,您的 PDF 中缺少所有必要的信息。

由于您是 iText 的新手,我强烈建议您不要使用早于 iText 7 的版本。您可能已经发现最新的 iText 5 版本是 iText 5.5.13,但这只是一个版本。 维护版本。在维护版本中,我们只为付费客户提供错误修复;我们不添加新功能。例如:新的 PDF 规范 ISO 32000-2(又名 PDF 2.0)仅从 iText 7.1 起可用。我们不会在旧版本中支持 PDF 2.0。

如果您访问官方网站,您会注意到 iText 7.1.1 是最新版本 ( iText 7 download page )。您在哪里找到 iText,为什么选择旧版本? (这不是一个反问句:我们想知道如何改进我们的网站。我们还想知道为什么这么多人在 Stack Overflow 上发布如此糟糕的代码;就好像他们不能找到教程。这很遗憾,因为我们在这些教程上投入了大量的时间和金钱。(但如果没有人阅读它们,那还有什么意义???)

您可以在 Jump-Start tutorial 中找到有关 iText 7 的更多信息。和 Building Blocks tutorial .

至于将XML转换为PDF,为什么不先转换为HTML,然后使用pdfHTML add-onchapter 4 中有一个关于如何执行此操作的示例。 HTML to PDF tutorial的以及 ZUGFeRD tutorial .

关于java - 如何将 XML 输出保存为 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49795393/

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