使用IText 7将外部字体生成为PDF后,外部字体未应用于HTML内的SVG内容

时间:2019-07-07 11:44:41

标签: itext itext7 html2pdf svg-font

我正在使用IText 7.1.6版本从HTML源生成PDF报告。我能够成功生成PDF报告。我对外部字体系列(例如TREBUC.TTF)有一个小问题,没有将其应用于HTML源代码中包含SVG元素的报告之一。字体已应用于HTML源代码中的所有其他元素,例如页眉,页脚和其他文本。我尝试为SVG添加自定义TagWorkerFactory和CSS applier工厂,但是没有运气。任何人都可以让我知道如何将不同的字体系列应用于HTML源代码中的SVG内容吗?下面是生成PDF和示例HTML源代码的代码。

byte[] data;
ConverterProperties properties = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String baseUri = ThreadContext.get(Constants.REPORT_PATH).toString();
String fonts[] = {baseUri + "/fonts/TREBUC.TTF", baseUri + "/fonts/TREBUCBD.TTF", baseUri + "/fonts/TREBUCBI.TTF",baseUri + "/fonts/TREBUCIT.TTF"};
 properties = new ConverterProperties();
 FontProvider fontProvider = new DefaultFontProvider(false, false, false);
 Map<String, PdfFont> pdfFontMap = new HashMap<String,PdfFont>();
 for (String font : fonts) {
     FontProgram fontProgram = FontProgramFactory.createFont(font);
     if(font.endsWith("TREBUC.TTF")) {
         pdfFontMap.put("NORMAL", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
     } else if(font.endsWith("TREBUCBD.TTF")) {
         pdfFontMap.put("BOLD", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
     } else if(font.endsWith("TREBUCBI.TTF")) {
         pdfFontMap.put("BOLD_ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
     } else if(font.endsWith("TREBUCIT.TTF")) {
         pdfFontMap.put("ITALIC", PdfFontFactory.createFont(fontProgram, PdfEncodings.WINANSI, true));
     }

     fontProvider.addFont(fontProgram);
 }
properties.setFontProvider(fontProvider);
properties.setMediaDeviceDescription(new MediaDeviceDescription(com.itextpdf.styledxmlparser.css.media.MediaType.PRINT));
byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(byteArrayOutputStream);
PdfDocument pdf = new PdfDocument(writer);
OutlineHandler outlineHandler = OutlineHandler.createStandardHandler();
properties.setOutlineHandler(outlineHandler);
properties.setTagWorkerFactory(
 new DefaultTagWorkerFactory() {
    @Override
    public ITagWorker getCustomTagWorker(
        IElementNode tag, ProcessorContext context) {
            if ("svg".equalsIgnoreCase(tag.name()) ) {
                return new SvgTagWorker(tag, context);
            }
            return null;
        }
} );
properties.setCssApplierFactory(
    new DefaultCssApplierFactory (){
        @Override
        public ICssApplier getCustomCssApplier(IElementNode tag)  {
            if (tag.name().equals("svg")) {
                return new SvgCssApplier();
            }
            return null;

        }
    }
);
NormalPageHeader headerHandler = new NormalPageHeader(baseUri + "\\images\\logo.png", userData, headerData, pdfFontMap);
pdf.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
PageEndEvent pageEndEvent = new PageEndEvent(baseUri + "\\images\\FooterLineExternal.png" ,pdfFontMap);
pdf.addEventHandler(PdfDocumentEvent.END_PAGE, pageEndEvent);
HtmlConverter.convertToPdf(htmlSource, pdf, properties);
data = byteArrayOutputStream.toByteArray();
pdf.close();
return data;





public class SvgCssApplier implements ICssApplier {
    @Override
    public void apply(ProcessorContext context,
            IStylesContainer stylesContainer, ITagWorker tagWorker){
            Map<String, String> cssProps = new HashMap<String, String>();
            IPropertyContainer container = tagWorker.getElementResult();
            if (container != null) {                    
                cssProps.put(CssConstants.FONT_FAMILY,"Trebuchet MS");
                cssProps.put(CssConstants.FONT_SIZE,"50.0pt");
                stylesContainer.setStyles(cssProps);
                BackgroundApplierUtil.applyBackground(cssProps, context, container);
            }
        }
    }

示例HTML源代码

<html>

    <head>
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style type="text/css">
    /*  ------ Global settings */


    * {
            font-family: 'Trebuchet MS';
            /*background-color: #ffffe0;*/
        }

        body {
            text-align: justify;
            counter-reset: chapter;
        }

        /* ------- Pagination */
        h1 {
            page-break-after: avoid;
            page-break-before: always;
        }

        p {
            orphans: 3;
            widows: 3;
        }
        svg {
            font-family: 'Trebuchet MS';
        }
        .noBorder {
            width: 100%; 
            empty-cells: show;  border-collapse: collapse; background-color: white;
        }
        .printTable{
            width: 100%;
            empty-cells: show;  border-collapse: collapse; background-color: white;


        }
        .addbreak {
            width: 100%;
            page-break-after: always;
        }
        .sectionHeading {
            background-color: #00843D; 
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: white;
            font-weight: bold;
            margin: 0px;
        }
        .heading {
            background-color: #84BD00; 
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: white;
            font-weight: bold;
            margin: 0px;
        }
        .sampleHeading {
            background-color: #84BD00; 
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: white;
            font-weight: bold;
            margin-top: 45px;
        }
        .subHeading {
            background-color: gray; 
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: white;
            font-weight: bold;
            margin: 0px;
        }
        .subHeading2 {
            background-color: #C0C0C0; 
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: black;
            font-weight: bold;
            margin: 0px;
        }
         .printTable tr p {
         padding-Left: 20px;
         }
        .printTable tr th{
            border: 1px solid #D9D9D9;
            font-size: 8pt;
            font-weight: bold;
            background: #F8F8F8
        }
        .printTable tbody tr {
            /* border: 1px solid #D9D9D9; */
            background: white;
            height:15px
        }
        .printTable caption {
            background-color: #84BD00; 
            border: 1px solid #D9D9D9;
            text-indent: 0px;  
            font-size: 10pt;
            vertical-align: middle;
            text-align: center;
            color: white;
            font-weight: bold;
        }

        .printTable tbody tr td {
            font-size: 8pt;
            vertical-align: bottom;
            background-color: white; 
            border: 1px solid #D9D9D9; 
            text-indent: 0px;  vertical-align: 
            middle;
            text-align: left;
            padding-left: 5px;

        }

        .printTable th {
            font-size: 8pt;
            text-align: center;
            padding-left: 5px;
        }

        table.report-container {
            width: 100%;
            page-break-after: always;
        }


        thead.report-header {
            display: table-header-group;
        }

        tfoot.report-footer {
            display: table-footer-group;
        }

        .table-header {
            font-size: 8pt;
            width: 100%
        }

        td {
        white-space: pre-wrap;
        white-space: -mos-pre-wrap;
        white-space: -pre-wrap;
        white-space: -o-pre-wrap;
        word-wrap: break-work;

        }

    /* Default left, right, top, bottom margin is 2cm */
    @page {
        margin: 20px;
        size: Letter;
        margin-top: 100px;
    }

    /* First page, 10 cm margin on top */
    @page :first {
        margin-top: 100px;
    }

    /* Left pages, a wider margin on the left */
    /*@page :left {
        margin-left: 1cm;
        margin-right: 0.5cm;
    }

    @page :right {
        margin-left: 0.5cm;
        margin-right: 0.5cm;
    }*/




</style>    </head>
<body>
    <h2 class="sampleHeading">Testing Analysis</h2>
<div id="svg1" style="height:410px;width:100%">
    <svg version="1.1" style="width:100%;font-family:&quot;Trebuchet MS&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif;font-size:12px;" xmlns="http://www.w3.org/2000/svg" width="550" height="350" viewBox="0 0 550 350">        
   <path id="lineAB" fill="none" stroke="red" stroke-width="3" d="M 100 350 l 150 -300" />
   <path id="lineBC" fill="none" stroke="red" stroke-width="3" d="M 250 50 l 150 300" />
   <path fill="none" stroke="green" stroke-width="3" d="M 175 200 l 150 0" />
   <path fill="none" stroke="blue" stroke-width="5" d="M 100 350 q 150 -300 300 0" />
   <!-- Mark relevant points -->
   <g fill="black" stroke="black" stroke-width="3">
     <circle id="pointA" cx="100" cy="350" r="3" />
     <circle id="pointB" cx="250" cy="50" r="3" />
     <circle id="pointC" cx="400" cy="350" r="3" />
   </g>
   <!-- Label the points -->
   <g font-family="sans-serif" font-size="30" fill="black" stroke="none" text-anchor="middle">
     <text x="100" y="350" dx="-30">A</text>
     <text x="250" y="50" dy="-10">B</text>
     <text x="400" y="350" dx="30">C</text>
   </g>
    </svg>  
</div>
<span>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum
</span> 
</body>
</html>

0 个答案:

没有答案