External Font is not getting applied to SVG content inside HTML after it gets generated to PDF using IText 7

北城余情 提交于 2020-01-06 06:42:19

问题


I am using IText 7.1.6 version to generate a PDF Report from the HTML source. I am able to generate the PDF report successfully. I have a small issue with external font-family like TREBUC.TTF not getting applied to one of the reports which contain SVG element in HTML source. Fonts are getting applied to all other elements like header, footer and other texts in the HTML source. I tried to add the custom TagWorkerFactory and CSS applier factory for the SVG but there is no luck. Can anyone please let me know how to apply a different font-family to theSVG content in HTML source ? Below is the code to generate PDF and sample HTML source.

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);
            }
        }
    }

Sample HTML Source

<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>

来源:https://stackoverflow.com/questions/56921868/external-font-is-not-getting-applied-to-svg-content-inside-html-after-it-gets-ge

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!