У меня есть XSL-файл, и я преобразую его в html, затем я использую следующий метод createPdf
конвертирование html в файл PDF.
Я подпишу печать. поэтому я использую methodA, чтобы найти местоположение некоторых ключевых слов.
этот код работает хорошо, но когда я комментирую код font2 или использую какой-либо другой китайский шрифт, файл PDF генерируется нормально, но methodA выдает исключение , В чем разница?
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at com.itextpdf.text.pdf.parser.TextRenderInfo.getCharCode(TextRenderInfo.java:429)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getWidthAndWordSpacing(TextRenderInfo.java:399)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getPdfStringWidth(TextRenderInfo.java:357)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getPdfStringWidth(TextRenderInfo.java:362)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getUnscaledWidth(TextRenderInfo.java:173)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getUnscaledBaselineWithOffset(TextRenderInfo.java:213)
at com.itextpdf.text.pdf.parser.TextRenderInfo.getBaseline(TextRenderInfo.java:184)
at com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy.renderText(LocationTextExtractionStrategy.java:219)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.displayPdfString(PdfContentStreamProcessor.java:311)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.access$3500(PdfContentStreamProcessor.java:80)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor$ShowText.invoke(PdfContentStreamProcessor.java:512)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.invokeOperator(PdfContentStreamProcessor.java:268)
at com.itextpdf.text.pdf.parser.PdfContentStreamProcessor.processContent(PdfContentStreamProcessor.java:374)
at com.bdfint.trade.order.util.PdfProcessor.main(PdfProcessor.java:320)
код здесь:
public byte[] createPdf(byte[] html) throws IOException {
DefaultFontProvider fontProvider = new DefaultFontProvider(false, true, false);
FontProgram font = FontProgramFactory.createFont("/SourceHanSerifSC-Regular.otf");
fontProvider.addFont(font);
FontProgram font2 = FontProgramFactory.createFont("/SourceHanSerifSC-Bold.otf"); // markAXXXXX
fontProvider.addFont(font2); // markAXXXX
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setFontProvider(fontProvider);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
List<IElement> iElements = HtmlConverter.convertToElements(new ByteArrayInputStream(html), converterProperties);
Document document = new Document(new PdfDocument(writer));
document.setProperty(Property.SPLIT_CHARACTERS, new SplitAllCharacters());
for (IElement iElement : iElements) {
document.add((IBlockElement) iElement);
}
document.flush();
document.close();
return baos.toByteArray();
}
public void methodA() {
PdfReader reader = new PdfReader("d://output.pdf");
LocationTextExtractionStrategy renderListener = new LocationTextExtractionStrategy();
PdfContentStreamProcessor processor = new PdfContentStreamProcessor(renderListener);
PdfDictionary pageDic = reader.getPageN(1);
PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
byte[] bytes = ContentByteUtils.getContentBytesForPage(reader, 1);
TreeSet<Float> ySets = new TreeSet<>(Float::compareTo);
processor.processContent(bytes, resourcesDic);
renderListener.getResultantText(textChunk -> {
System.out.println(textChunk.getText());
return true;
});
}
XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="utf-8"/>
<xsl:template match="/orderNotificationInfoDTO">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta content="always" name="referrer"/>
<title>通知</title>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
padding:30px;
font-size: 14px;
}
.title {
font-weight: bold;
font-size: 1rem;
text-align: center;
margin: 20px;
}
.clearFloat::after {
content: "";
display: block;
clear: both;
}
table {
width: 100%;
border: 1px solid #ddd;
border-collapse: collapse;
font-size: 14px;
table-layout: fixed;
}
th {
background: #f4f4f4;
}
td,
th {
border: 1px solid #ddd;
padding: 10px;
word-wrap:break-word;
word-break:break-all;
}
.tableItem {
margin: 15px 0;
}
.viewContract {
margin: 0 auto;
font-size: 14px;
}
.num {
float: right;
}
.operateUser {
font-size: 0;
margin: 10px 0;
}
.operateUser span{
font-size: 14px;
display: inline-block;
width: 50%;
text-align: center;
}
.sign {
text-align: right;
line-height: 20px;
margin: 20px 0;
}
.bold {
font-weight: bold;
}
.tipDetail {
text-indent: 2em;
}
.padding20 {
padding: 0 20px ;
}
.marginBottom20 {
margin-bottom:20px ;
}
</style>
</head>
<body>
<div class="viewContract">
<div class="title">通知单</div>
<div class="clearFloat">
<div class="num">编号:<xsl:value-of select="child::settlementNo" /></div>
</div>
<div class="tableItem">
<table>
<thead>
<tr>
<th>货物名称</th>
<th>生产厂家</th>
<th>材质</th>
<th>规格型号</th>
<th>重量</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="./goods">
<tr>
<td><xsl:value-of select="brandName" /></td>
<td><xsl:value-of select="factory" /></td>
<td><xsl:value-of select="material" /></td>
<td><xsl:value-of select="spec" /></td>
<td><xsl:value-of select="applyWeight" /><xsl:value-of select="unitName" /></td>
</tr>
</xsl:for-each>
<tr>
<td class="bold">备注</td>
<td colspan="5"><p>
<xsl:value-of select="child::remark" />
</p></td>
</tr>
</tbody>
</table>
</div>
<div class="tip padding20">
<p>注:</p>
<p>金卡释放的空间广泛大概。</p>
</div>
<div class="sign">
<div class="signUser"><xsl:value-of select="child::seller" /></div>
<div class="signTime">签发日期:<xsl:value-of select="child::signTime" /></div>
</div>
<div class="tip padding20">
<p>申明:</p>
<p class="tipDetail">
一些中文字符
</p>
</div>
</div>
</body>
</html>
</xsl:template>