Внешний шрифт не применяется к содержимому SVG внутри HTML после его создания в PDF с использованием IText 7 - PullRequest
0 голосов
/ 07 июля 2019

Я использую версию IText 7.1.6 для создания отчета в формате PDF из источника HTML.Я могу успешно создать отчет в формате PDF.У меня есть небольшая проблема с внешним семейством шрифтов, таким как TREBUC.TTF, который не применяется к одному из отчетов, которые содержат элемент SVG в источнике HTML.Шрифты применяются ко всем другим элементам, таким как заголовок, нижний колонтитул и другие тексты в исходном коде HTML.Я пытался добавить собственную фабрику приложений TagWorkerFactory и CSS для SVG, но безуспешно.Может кто-нибудь, пожалуйста, дайте мне знать, как применить другое семейство шрифтов к содержимому SVG в источнике HTML?Ниже приведен код для генерации 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>
...