- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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-on ? chapter 4 中有一个关于如何执行此操作的示例。 HTML to PDF tutorial的以及 ZUGFeRD tutorial .
关于java - 如何将 XML 输出保存为 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49795393/
我是一名优秀的程序员,十分优秀!