itext html2pdf с китайскими шрифтами - PullRequest
0 голосов
/ 06 марта 2020

У меня есть 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>

...