Parsing html to pdf with iText, image base64

29,400

Solution 1

Here is the java implementation of custom image tag processor:

package com.example.itext.processor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.NoCustomContextException;
import com.itextpdf.tool.xml.Tag;
import com.itextpdf.tool.xml.WorkerContext;
import com.itextpdf.tool.xml.exceptions.LocaleMessages;
import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException;
import com.itextpdf.tool.xml.html.HTML;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

public class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image {

private final Logger logger = LoggerFactory.getLogger(getClass());

/*
 * (non-Javadoc)
 * 
 * @see com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag, java.util.List, com.itextpdf.text.Document)
 */
@Override
public List<Element> end(final WorkerContext ctx, final Tag tag, final List<Element> currentContent) {
    final Map<String, String> attributes = tag.getAttributes();
    String src = attributes.get(HTML.Attribute.SRC);
    List<Element> elements = new ArrayList<Element>(1);
    if (null != src && src.length() > 0) {
        Image img = null;
        if (src.startsWith("data:image/")) {
            final String base64Data = src.substring(src.indexOf(",") + 1);
            try {
                img = Image.getInstance(Base64.decode(base64Data));
            } catch (Exception e) {
                if (logger.isLogging(Level.ERROR)) {
                    logger.error(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.HTML_IMG_RETRIEVE_FAIL), src), e);
                }
            }
            if (img != null) {
                try {
                    final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx);
                    elements.add(getCssAppliers().apply(new Chunk((com.itextpdf.text.Image) getCssAppliers().apply(img, tag, htmlPipelineContext), 0, 0, true), tag,
                        htmlPipelineContext));
                } catch (NoCustomContextException e) {
                    throw new RuntimeWorkerException(e);
                }
            }
        }

        if (img == null) {
            elements = super.end(ctx, tag, currentContent);
        }
    }
    return elements;
}
}

Following code snippet registers the custom image tag processor and coverts an HTML document to PDF

public static void main(String[] args) {
    convertHtmlToPdf();

}

private static void convertHtmlToPdf() {
    try {
        final OutputStream file = new FileOutputStream(new File("C:\\Test.pdf"));
        final Document document = new Document();
        final PdfWriter writer = PdfWriter.getInstance(document, file);
        document.open();
        final TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
        tagProcessorFactory.removeProcessor(HTML.Tag.IMG);
        tagProcessorFactory.addProcessor(new ImageTagProcessor(), HTML.Tag.IMG);

        final CssFilesImpl cssFiles = new CssFilesImpl();
        cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
        final StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles);
        final HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
        hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
        final HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
        final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
        final XMLWorker worker = new XMLWorker(pipeline, true);
        final Charset charset = Charset.forName("UTF-8");
        final XMLParser xmlParser = new XMLParser(true, worker, charset);
        final InputStream is = new FileInputStream("C:\\test.html");
        xmlParser.parse(is, charset);

        is.close();
        document.close();
        file.close();
    } catch (Exception e) {
        e.printStackTrace();
        // TODO
    }
}

Solution 2

It's possible to replace the built-in tags processors of iText(Sharp). Here is the C# code with custom image tag processor which supports base64 images too. It's easy to convert it to java (base libraries iText and iTextSharp have the same API).

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.html;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;

namespace CustomHtmlWorkerTag
{
    /// <summary>
    /// Our custom HTML Tag to add an IElement.
    /// </summary>
    public class CustomImageHTMLTagProcessor : IHTMLTagProcessor
    {
        /// <summary>
        /// Tells the HTMLWorker what to do when a close tag is encountered.
        /// </summary>
        public void EndElement(HTMLWorker worker, string tag)
        {
        }

        /// <summary>
        /// Tells the HTMLWorker what to do when an open tag is encountered.
        /// </summary>
        public void StartElement(HTMLWorker worker, string tag, IDictionary<string, string> attrs)
        {
            Image image;
            var src = attrs["src"];

            if (src.StartsWith("data:image/"))
            {
                // data:[<MIME-type>][;charset=<encoding>][;base64],<data>
                var base64Data = src.Substring(src.IndexOf(",") + 1);
                var imagedata = Convert.FromBase64String(base64Data);
                image = Image.GetInstance(imagedata);
            }
            else
            {
                image = Image.GetInstance(src);
            }

            worker.UpdateChain(tag, attrs);
            worker.ProcessImage(image, attrs);
            worker.UpdateChain(tag);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var pdfDoc = new Document(PageSize.A4))
            {
                PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
                pdfDoc.Open();

                FontFactory.Register("c:\\windows\\fonts\\tahoma.ttf");

                var tags = new HTMLTagProcessors();
                // Replace the built-in image processor
                tags[HtmlTags.IMG] = new CustomImageHTMLTagProcessor();

                var html = "<img alt='' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAodJREFUeNpsk0tME1EUhv87UwlCREhRFpi4cGMMRrTE4MaoxBhAsDyMssFHfCQu3BlXGuNKNy5NmqALoqEEMJWCgEUjYojllSpofIUNBNqmIKU6OnQennunUxvgJF86957z/+d27hkGigMlDJfOAmV7AcYsKGqIZljRSvhNE+CMTwEtXmBy2gQb7mCQJUBKkTIQYtfJYCNMAxO9hzq5CYmFiWFY6ISE9VFLRedc1SONeqwf+uJLuKreNPI9nltbLG0orhpqUCM90DRVoEbJ5MSLho1MMg1O0bHOuyoD9crCcxL+xa0HqwL+rEQHsb/CW89reO1aAyEuq+yp+zXvg66rgng8LrDXSmwYpUc8dZkmDsJNL+NCeVVXbWK+O32cpJ7E6OgkwuEwrl8phaHrVsfYD+x03XTPjN3nzZnD0HGxvPppTSLcLwo0I4lldRFK8jdCoZBlJquAbBnr0BD9GUTRvubahclW5qDukqkpIqlodGQ1At3UxZXaIUvauqsyjBV+jZJEJ3s83HO5j+UWI7E6C4mp2EQCTixyV2CvbbKzNmN2zNfHtbzPM3p4FOy/M5CXtwsOKZmmsOi2IHMvyyFhJhgY4BqutQ/aRRstocEngZzswnQnO+x1lqTjy8hIgNdyDc+x5nomxrKJhpcSp2lSrx48WlZhGArynG5hsLLoE7/jQ59f0aR7ZBkdbf7U6Ge+mKYaBvdx8wwZXjtWvfswfTrp3Over29J8NAXYO1t/v/7csZA5U5/Q35nH+aKt8OMR2POPSUFOyRmorvje3BiCt4b9zBANTmwGvP/aMoZRluJbURB8APmnPlQliNLzk8flxbeh9Du8eId5bYQ2SnxH36b/wQYABNFRsIaESsTAAAAAElFTkSuQmCC' />";

                var styles = new StyleSheet();
                styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.FONTFAMILY, "tahoma");
                styles.LoadTagStyle(HtmlTags.BODY, HtmlTags.ENCODING, "Identity-H");

                PdfPCell pdfCell = new PdfPCell { Border = 0 };
                pdfCell.RunDirection = PdfWriter.RUN_DIRECTION_LTR;

                using (var reader = new StringReader(html))
                {
                    var parsedHtmlElements = HTMLWorker.ParseToList(reader, styles, tags, null);

                    foreach (var htmlElement in parsedHtmlElements)
                    {
                        pdfCell.AddElement(htmlElement);
                    }
                }

                var table1 = new PdfPTable(1);
                table1.AddCell(pdfCell);
                pdfDoc.Add(table1);
            }

            Process.Start("Test.pdf");
        }
    }
}

Solution 3

Add the below width and height of the image in the above code of Ajay Deshwal which is working perfectly for me.

package com.example.itext.processor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.NoCustomContextException;
import com.itextpdf.tool.xml.Tag;
import com.itextpdf.tool.xml.WorkerContext;
import com.itextpdf.tool.xml.css.CssUtils;
import com.itextpdf.tool.xml.exceptions.LocaleMessages;
import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException;
import com.itextpdf.tool.xml.html.HTML;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

public class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image {
private final CssUtils utils = CssUtils.getInstance();
private final Logger logger = LoggerFactory.getLogger(getClass());

/*
 * (non-Javadoc)
 * 
 * @see
 * com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag,
 * java.util.List, com.itextpdf.text.Document)
 */
@Override
public List<Element> end(final WorkerContext ctx, final Tag tag,
        final List<Element> currentContent) {
    final Map<String, String> attributes = tag.getAttributes();
    String src = attributes.get(HTML.Attribute.SRC);
    List<Element> elements = new ArrayList<Element>(1);
    if (null != src && src.length() > 0) {
        Image img = null;
        if (src.startsWith("data:image/png;base64")) {
            final String base64Data = src.substring(src.indexOf(",") + 1);
            try {
                img = Image.getInstance(Base64.decode(base64Data));

            } catch (Exception e) {
                if (logger.isLogging(Level.ERROR)) {
                    logger.error(String.format(LocaleMessages.getInstance()
                            .getMessage(
                                    LocaleMessages.HTML_IMG_RETRIEVE_FAIL),
                            src), e);
                }
            }
            if (null != img) {
                String width = attributes.get(HTML.Attribute.WIDTH);
                float widthInPoints = utils.parsePxInCmMmPcToPt(width);
                String height = attributes.get(HTML.Attribute.HEIGHT);
                if (width == null || height == null)
                    img.setScaleToFitLineWhenOverflow(true);
                else
                    img.setScaleToFitLineWhenOverflow(false);
                float heightInPoints = utils.parsePxInCmMmPcToPt(height);
                if (widthInPoints > 0 && heightInPoints > 0) {
                    img.scaleAbsolute(widthInPoints, heightInPoints);
                } else if (widthInPoints > 0) {
                    heightInPoints = img.getHeight() * widthInPoints
                            / img.getWidth();
                    img.scaleAbsolute(widthInPoints, heightInPoints);
                } else if (heightInPoints > 0) {
                    widthInPoints = img.getWidth() * heightInPoints
                            / img.getHeight();
                    img.scaleAbsolute(widthInPoints, heightInPoints);
                }
            }
            if (img != null) {
                try {

                    final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx);
                    elements
                            .add(getCssAppliers()
                                    .apply(
                                            new Chunk(
                                                    (com.itextpdf.text.Image) getCssAppliers()
                                                            .apply(img,
                                                                    tag,
                                                                    htmlPipelineContext),
                                                    0, 0, true), tag,
                                            htmlPipelineContext));
                } catch (NoCustomContextException e) {
                    throw new RuntimeWorkerException(e);
                }
            }
        }

        if (img == null) {
            elements = super.end(ctx, tag, currentContent);
        }
    }
    return elements;
}

}

Solution 4

the solution provided by Ajay Deshwal is a very good reference point to work on .png Base64 images in iText.

all i did was to goto my HTMLWOrker and edit the method startElement(String tag, HashMap h);

at this section of the method, if (tag.equals(HtmlTags.IMAGE)), blahblah.. just add anther check

if(src.startsWith("data:image/png;base64")){
        final String base64Data = src.substring(src.indexOf(",") + 1);
try {
        img = Image.getInstance(Base64.decode(base64Data));
} catch (Exception e) {
        throw new ExceptionConverter(e);
}
}
Share:
29,400
jd.carretero
Author by

jd.carretero

Updated on March 21, 2020

Comments

  • jd.carretero
    jd.carretero about 4 years

    I'm doing a PDF report in which I have to insert some html fragments. I'm done with iText5 and my code is:

    Paragraph paragraph = new Paragraph();
    HTMLWorker htmlWorker = new HTMLWorker(docPDF);
    htmlWorker.parse(new StringReader(...html string in here....));
    

    Everything is working fine but when in the html code there is a tag with the source in base64 like this

    <img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUh......" />
    

    it displays the following error:

    ExceptionConverter: java.io.FileNotFoundException: C:\data:image\png;base64,iVBORw0KGgoAAAANSUhEUgAAAOUAAADpCAIAAABUaWc6AAAgAElEQVR4nO2deXxTZdr3z8wDtK6AioAsohVFAesGMgjCIOrIzIBLBwd8B+ZFh0FnZNDRF3kUpoNsIooOCLi0jApaShegi3Sj+56kW5ZmOznZ0+xNQtM2bfP+cZfD6cnZsxZzfX5\QJuepCff3rnu674WyB+3uI0eg6L9AuIWNxYW5zVuo8nivMZtNFmc17iNJrvWePX5fDqDAUiqgMVyJZnQh9lstmi\6rgxtVHPKwBUIodFsEZm9iCuAc4Sq40iWCORw0aTKdq\VtyIbVTy6nZ7EI1WLIfFWmMwgNLgqzUKlWqxXAkjarfbE+1fOm5+\6jj1WgyCRVI+BilkERjFcths9kS7Xvws7bRwavX6xXLlVKjPSqk4iQ12sVxnyFKFuu86gwGkRwO0jENk2Rmj1CBwIja5\NF+z79XCx2ebXZbEJEH3UoKaT3DJguD5ouD2qclxGdCVapYRhWqVSGKxbnOOQWi7z6fD6xAlbYe6JOJCqDZ9DeO+jsG+ruG+odGGL7G5lMJhiGEQTxer3huGM\H4s5Xo0mk0RjjTqgiGvAeHnQ2TfU4xtijSe59fX1aTSa0F3vZ2exxatMqYrusqp1D1i9g+7+IfZrKAtDECTuKnCzWOHV5\OJ5NEJVAFZega9YYV0pFmtVrvdHrGnu2YsJnj1er1hjfxTSOcZcPUPDUYO1KvW19eHIEgUnng0W\R59Xq9UQms6jwD7v5ocDrS4r4BK4syrz6fL\JBK4Nn8LIv+qSiFvcNmFs0efX5fCJYE0lS1a4BZ190Pv2pLe4bMLRo8hrhTADT5cEIbqhY2OXLl8H5QhxZWosar1IFHGEfwDswRKbLviFnHyPZewfBmRat9B4WL08kh+NHCUwsOryazZaYOr6KBcmM3VIFHJW3YxRZFHj1+XwxcoIVg5JorBqtLvJvymixKPAa3XOBUSGhMp4hTmyR5lWj1UWdhlEhmdkjkcfdA7xFlFefzyczdkcdhVEksdoYL4fEWkR5hRF11AkYdVLYe+ILLWqR49Xn80UrSeAakFhtjHu0\kjyGuGA67UnmdkTDx1EkNfYqBYc7RLJf9ZFChHiFdFoo\5OXzOSaKw\201YhHiNe66hlczsQTTayLx3MWWR4DUecw2TxHJlBN6+mLJI8Bqtjiw\BwkR\c\KnQ07rz6fL57aElZJNFan0xnu9zFGLOy8xs8IIiCZ2fMz6Y8Udl7jzkBkpLD3yJSqcL+bUbew8xqbra+uVYnk8LVdvRheXnUGQ9Tfwp+bru0dWHh5jTsDUZHUaL9Wd2Bh5DUeGcBK6egt5DUDZZQXA6FfKeQ110jlQEpHbxxZMgsjr2azJeqUxI5aNEYUU2oJQ5RoITN2X3vdwMPIazxnAKuy9g6GvDYqQxYBVNh7rrFj2zDyKo4nEGKUW1vNkNdKUWdon1qhunbaGoSR1wj3bolliU1OhrBmlBdf5PND\gKuGWTDyGs88oqqTqZgzmt2TWU4XsO1gWy4eL2WNlsSc3eDAoad\ZyvgI0JMFEwIQKxySm3XSb+1ujP5woXrwrVtRB5VTp6K0WdgKHz9bXcdu5KR29mZSkrXjmHCBoUcGZlaVbVpWYV8WZ3tCMbLl6vgaYYDQo4q+oSFqPMytI6mYLVRYRGO\PIAKrilha2yCodvRf5fOxF8psaJGaC6vlRjWy4eI3xUUTUatEYz9fXksFExgEqibm7Uakubmlhu6zilFV1qaStrVmlJft8R9Wut2bXVAZeAfyBBXoyoxfZcPE6SjtkiU1OJr5m4EKrdPTyEX25UMQ8bsVKeY11VRIZ4aJbJZFR\yyhJwMj6jC99WG1cPE6GqthGxQwK4Yu8vntemuVRJbf1BAORmkXXanVzfypK0Wd2G2cwt4zGlNmw8Vr1OHjIA6O5uhSdk1lq64L\X1lZs+oO7ANC68+ny\q8MV5JVReYx32V5aZPaOrNDwsvDqdzqjDx0G0juA1oOKWFtxvPboyueK8XlWNVB51nsItwuQEicY6WlK8w8LrKC0r+Dnw2kCShCRE9KOikCYsvI7SBhnNKm3UeQq3WjSkjXbEo6FrZ1h4HaWHsWHl9Uxl+dma+pymdlTZDYLsBj7636y65syqinDzKjZRuWqxX2Eb5\Wq+Ig+lIBWlOTUC3J5kgstqoIOU4HQwlB5bdpcniS7rulMRVnIeaXOpFHYe2K8ZScpr3a73XDFLBZ2UbpRymu73ho8EGerq3N5kvx2A3NAqdht1ZwXKLPreWcqy4N\bVlVl2hvgsLeE8tBWVJeHQ5H4BdNJhM6iQ+GYRRoj2dE6+dRyisuX4SVilp4PKRTd9lWr7aFhNRAnRcoc+oFwYCLC76SSWq0x2wvb2Je9Xo9h2sBdmEYVml1XT2DxsuDUUeQubgdFmRVlfE1Ml2PzdTvBGrtcgSiJjDaqmBrkcRSILR8mVcXJLjneNKz1VyyFLKqLlH7r6hiNlxAzKtWG7IitYEhv3dgyNk35OgdNHhilGA0yZW5ztVVtuoUWFJN\U691wmgxKqk04o+oE7Sdvfs2RAErVr75\VvvLv7xJlcvo7zcptd18QB2XY9o1Sk2AwXEPDq8Xj6+vrC95T9g34wr9UUGwsw27BrZmUpXyPDYopKZLUHglUut2IfU9PRBGFs8rQZu0+cCcZJYLvWZlaWYrMIKBSDJTQEvKpUqki+gt6BoR7fkKOX3YDgUIltDOuioEHjMRPCaup3VsMEzms1PGIN3n1oPxRgb+05EoyHkMuTsAomMEQ2BvdeBLxardbIvw7UegeGnH1DIfEc5LbL1InVzHtYAAdA1IWQkWrqd2q9zkKRNRCmBs0IXlc8uxJLatKcebtPnDlw8lyQTm1emz6rjkWVWGZlKVnNDFZSoz2mjmrxvBoMhqi8jkAbGPJ7fENW76DWzZFXdL+f11h3kc+vkcqbVdp2vRXk27fqupjn\1eIBBSkAoltBDutAqFFYLzKq9plSkhMxPI698H5EARt3r4nSF6BzjWLWH1cMEFWqIyhzG48rwgScy6L3+\vGxyys3QYqIP\WVWXmMNaJxcaeu20vGp6iHltN9uxvM5Lno\ldV7y\CZZe9qFouBhFZodSpdTZtOdqyOojSFTgwJu11uBGhQw2sarRiov5DWDwoTYOfcawavX6w3rTit46x0YMvfQuwqws5+wnomtsqvLZDYdLamoyuV4f6BcbtX0OLCPefTxBVhe77nv3ufXvqR2mYRmB6E7wVzoEyHuLlbIUgiEbBX2nhjJORzBa4R3WpzNN+h39A5qyP0EDvEpQlg7LVrmsJr6nQLjiP1Wrcpq7MM\Zveh\Un3zkZ5ffTxBe\sfA9o6473tv7r0IGT57jFaJWu4Zia3uvU9dgKmmpCgizwGYQIl5B8yG0Er2zPXSNgIHwL5OwblqVn0HSZNJrLqvkPmTIrS1mtrMMLm8eJ0sPXD7utUrM6pyR\89bXFy9bcvuUyRAEJV5xYWfNmrVly5ZZs2YFRgxuuGn8r55atXn7HuZbManDAdySMpkV8YQM2eyaSuDxx0JV7VVeIwwrSqGrf5hCe++g6fKw1EGEBfIa6zi\N59+m5ay8U+b\7mtQdbOFlagMpm1UGQVWe2mfmdOSf7za19KSEz85ZgxWBbLy8tbWlokEgm4FcuXLw\kNXHCRGyMduXzf6QFFzwpcKOLJVZjn1PjMYfEMaiSyMC91UV7O36V15DstKxWKziV7b7sRZfDrp5hCiMQYWVb44pTWl7OvXMfgCBo\ITxOSX5HHhtN9uVLueJU2nzkuePu\Gm2c+svn\1WhyvqampHpOx5sP\BTeNkFcIgm5Num\2M6sf2bBl7ouvTE1+bEzidZOnzVj\xrunKkSEvKrcDuy2D+zzNB7zRUGw5buZlaWgB4LM2B3d1IJhXn0+H8VOy+v1oqktKpUKhmEYhhEEQb8Y+CNRqeeW2y4H2aLiZME5mU33\NqXuCGrdpl2H9o\486ZN0+bOffFV1bsPJi04rlAEJcvXw6XFGasWupQyvzkvAIbd+NNdz7x68Vv7li+Y9\cF1+5Nem+G24av2rtnzPrFYSBCJRXsMSa+p2GXnshj\tnDhBa+BXd8NYwr3a7Hb5iZFlXrCwq\V1K2tqCeUuyqsoq2ho3b30d3cK\9NJLGXnZapeJCayff3Ps0ccX3Dj5juT1r67YeXDh5m03T5tJiGBiYqJNjZx7ZU2\x+2n4xW73N6\eu3yHfse2\T3W5PugyDoD6\9A5t+UCiyyrsdQrMD\S+62zP02oP3ZdGmG1E8p712+hEFn73aqlMMf6ZrpLsP7X9xbQpIqpw1a9a85Pmbt75+4lRau0YaSGpOST4g9f7Va1fsPLhi58H7Vr047sabKOArLy\P+79\kBec8zPmFdiYxOtmP7N6xc6DyetfTZwwcfpds7d\BWKLDbbBncOrOuxXWgIqvcMmo4YxfBW2HiN+GQY2NkfTC8gwhOsv775xrZt21BWJt0398bJd8y4c+bLG9Z\dPTTmo4mqVn9\NqXEidMnL92IyB10evvXH\b7bTYpaamnntlzdnnn\KYjKx4BTZ5bvLyHfuefPffE+9MgiBo5fN\JDw+wP06oi4kyD9pqdUN7rZYbQwTOdQWvv6EUWgGLzTaufmvxS1NZP7oxs2bsGvb1OTHFm7eBjZAiRMm\nLMmNnPrF6+Y9+KnQeXvLVz0n1zGQK3fPnyjFVLM1YtvfTeVg68QhB04+Q7Fr3+zvId+6Y9ugiCoDV\+isW1mIJ\pwCiK+RcYYVjRIMIxuN8FbY+mdFaXgBh5rszMpSuNtI4Zh+dPRT3KH\5LnJc1985ZENW5bv2LfkrZ0AX1a0JSYm\vi7ZQDZh6dP5cArBEFjEq8D6\r9q9dCEPTMC+tEVnutyiqy2gPPKVBx23udr6\F9TmMilcQLl6NJlNUeEXYN7PmIZ20e6mC6pLxE8Zzo4rMdi16EPD6wK2kV5542+3zFzxBfZ27lj29YufB2c+shiDonZ3v0f4uGo85u5p1JSNha8TIxwrCxavX6w0hghUd8JmyZqC08xU\ljSi\z1T1ixARiTMS61uXJ9hCmVVlVHks44IrGqkIM7FyhISE59f+9IPeVmB31o5cyoTXtFo66kK0YGT5w6cPLd5+571b7yL5fjWpPuefPffdy17GoKgk1mnaX8XHsLuvLpGKid7ayJ8ghDOeRtGqtxTVvqusPbY2WIyFfFluMczr8wmqxSgWGhxCVZkmK54duXn3xxr10iNfU6h2bFg6VO4x0y6LhHwOum6RMKLDGNNtJcqEFpy+bpHl6xAH5Y4YeLCzdtmPL7k9imTcUEMtct04lTaimdXjp8w\vm1L33+zbFWdSfz8FZeYx3F7Aap0R7JSq9RMM9I0uWmgPXY2eLsKnwPM4RZ\WB+Yw0rWFGVNle\v+dfi5ctufHm4aVx\oIn5i944vfr\vzmB3syLjUIjLbWLoe82yEw2kCM6YPPvw1k8cPFD9HyCkEQWcFMLl\3q6dWoQ\75Zgx969ee2vSfS9vWI99tZ9\cyzwmrOS7l6V8uKOj\bSOve0JYqiCFZ6hXNeXIhCBDUSLTWvJ\OrA38KdvbTxgqEJhU3Xq9+sOqYVm\n8nUTA+JcKbPvzFi1dELCOGpe5yQ\RnHllc\EftgELgoba6m5hVryQsXbPjblk+\TWPlCWAVsbKZcPoDSlVIeL1Q10HN67GzxXI7vm2JxNxNDeuFBo6LK1Yqt0NgtNWqrIGZr4Fa86e\4kC548brM1YtpYYJ2Aeff8scWQiCFi9bwpxX1Cbccsurb21FbxGamUUrsTZC4diIzjsWINYfShqK+DLYwWKW1de5l2h5bdXgd6+0gS2+mp3nCiSy2tvNpNEixOOUOR0Co61BY6uCrVWwVWC0Cc0OebdD63WWNlcHInLk1wsCvxho8xc8Qf3H8IfX\oH7kWZ5O1teIQh64KFk7F2iHfWBKjKHtOGdJ391tetyZ1e1oHh9V1gbSBihGuVGWliPnS3ObxRJutzYH6Ru7H+mogTbOkDpcgqMNoHRJnU45N0EYXbAYoXCikbjsVUuzIUrLoAgaE3SDIYkHckqJyS1pNNaBVvLZNb1b7yLfTzqxeaU5DPndey4cdgbxaTAC0hm7I7AxiuMvPr9fonGKrf3FjZ1nsgpxRF2Iqe0rFVB+JtLutw1Em1uTVvahUomsGL\DAqbOpvhLqnVTb24lnW0YDHCfZprvSMgM\Y5+XoCP7WkczjPlbk+Ovopjg\azRZqTz73AiGvaGK46Uqx+G9+85vc3NyFCxdKzWq2vEIQdCI7A71RJW1tzD8JI9BiI7y88qQI9af5DyUNYF2U23vrpfr8RtHJ\GpWjBLqv4U08XCFw4C+x\JufJ2gzHl1iZU5HSWdVL5pkcRSq7KCtFdaXqVmdUJCAit6UJt42+2EzWDq1SPyWj7\5tjJkyf9fn9qaiqIxbLlddfhj9EbxaRF3FWXwN4T7uzYMPKq1eplXR5atr7OvXSqqC54RrE6VVxCAWt2TRX2Da5V4XFEM0UaGW\C66k8FXB1gaNDXgXIKQFpPcOL9XLV73AjVeIZNdVobDi\ipeeDll\79ixYtWrjkiceXLLl\Pn3AGGspG\80IorCJpU53EtsGHnVGww611BI1ktWOpFVnHGJanEtabuaiqVyExRh83Q2sm8FrwMnz3HmddXaPwdesFiC51VqVo8dNxaCoF\84hcQBG3\+CtWz7JgyWIOIa3ILLHh5dXg8jOJRrFXEcV30\JojglatAr0rSUMoNaqrGTfCokmT2O6x8LZ5GkzCC8YmIqFTSubmXQvq2e5Y+YM7O0q5DUz5xVxDYjkYQwUhJFXp9NpcPlrOnURXl+\u0jDKxoZIOsgVCazkn0rJMJt5FnZJ6d\IrxmNWwT2xwgjiEw2r48X8GZVwiCcHeM7Xz78CUVhJ1XqZnehQ2l6JyB8\VXjwlw7QKwImzjylanKkS7T5xZ\8a76994Fz3rBxnWnG39G+8SPlexBH9mMedKiuOvf5vC9lm+L8ofEatmWS0i1hrDFNsKO69a1yDbsBT+8\1C5Zmy5pP5Vbivg+SsH0oasF\85jzN4lonE6JRqmIJ6QoazOL6ZV7d33Z9DPKnfjlmzMQ7k6YmP3b\6rWPbfo7qEGY8fgSDqROv2v2\AVPYHktFFn5epvM6UADcJoeh9DsAG0SPzn90\S7ZkMQ9LddH7N9LmyIIKO8uKy9gxWviGtAqgjLxiu88SyDy693DWFPChjqVFFdWatCgFjRg9ZAPxh7dwSItbxDkV3d+EMpVWQgo7wY22MQjf+HREeyylc+\8dxCQm3Jt2XtOK5RzZsWfT6OwDQFTsPPrbp7\evXnvXsqfvWvb0nU\8mgOvuJ5whSIrNu6Gk97rFNscHxw6On\BE5n1iiB5za0lyNCgXWLDQVTY11eDy1\RoWLC6Imc0tyatkY58YAoQl5hZ3+Lxshqijs22zUkEYBTFaK\7fp4+pwHpj26CNSvgiquRzZsmf3M6qnJj028MwnXf4Cb\eG1f2CfF3ir1Pr8m2MLn3yqQGhh+1yBeVsMWxyPkCZkXdpRCxevbrdHaXQAXoX6bmpST+ZXV3TA1EkFOF6\uVDMto4go7z4TEUJ7h1lG2HFkZqy+a27lz29cPM2sIgu3LwtacVzN06+I3g6Aw2bCMvwXO2jo58u\vVTHCJor29\J\Du5dZWlwtFLRpjFJNgwsKr1+uVaS0AVoPLr3MNkZ1yfVdYWy9l5MvjeP2hlB2pw5utgJwsLdHEAVqlFwme\O2Ldy17+sl3\w1Kq6c9ugjbQSgchqa8MD8Efmfne+Bnf\HLX7J6LmyWFqGKW1oalWq0XDZiS2zoefX5fFLEgMIKFOjCfp17qaKDRYIsjtcfKYMApHe5lRf4prabCYYOUOhvuz6edM+cxW\uAF4pWVOMkNvdc+YVCC2tXfRuAKrdh\a\vGH9sdOn7pjB7kXijrgoRJ0QE\IlNvS8SpRaHKwGl78S48KeyCkt4ssCM1aplVvThuWVA6wZ5cUFLR24XBYQKGCSvVogtGTWK5787YvYdhVhQpPQJt52O7ZVNyvNuDMSvMJ2T7iXWI68ytQmg8sv01o6YV2nHFaqEL3B4PP5xHIkEFaDyy\UOVFXlaEDgBMubsWN13M8aZHEEritljroN17pRYLpcx5YuHnb4jd3TJ6bHCYoqY0s1zG6vKqcvRK1uqWtnscrF8EKlXPEShTaxrFceJUriaGkkL576OvcSyfzq3FZqsyFy0Pgxut5gRLAx9PZcDnXgVkvuFjVnfMfWfLWzuT1r4Zks481Jv1ggJ2vbeTG6+Jl7CK+zHmtbuPzBZU8XjkqQWutzDAimBDCahnWvLrdHpXZy5ZXg8tf0iJnVVYQDl4vtKhQBMvlVsRz9R1FPKQHsOlFghtuuXX5jn2gLUXIbcbjS6ibbaH2waGjkeGVdr+F6lJ9GRZWVO2SVnShDWGbAta8ihUaDrB2wjqRnHs5l9zei8v4Dp7XAqGlUGTFNpkiTHDJrFdMu+c+EKjiRCN095x5oHr2D6\9A5zNgjYCn5z+6UhWOQRBiRMmMvxLeGLlqsjwShjPYsUrj1cuN9lCvsSy4xXREOylaCVTm7xer0ar48yr0IiP4IaEVyDsJqa1a8TQi1y+bsrMWUve2knRbggckz753AuAxbf2HAE4knUVxgkc285+ZjWTvIJxCQmwg1Fzz1jgVaq7ulEJVV4sC159Pp\S6GILq1iOgNQHn88nMxPtHxmoGe4KCa+o\4pbZbFBA+yMwl89ter+1WspYL17zjzOA2CBQDD\xsl3LHlrJxPPOC07iwOvL29Yz4pX2r4EbHmVmT0hyYBhwatEDnNwA7CvUiTn2GSzrFUREl5zeRJCaLAlJejxwebte6YmPwaa\BDauIQEshpAVrp7zjwIghi6HGs3\t9w8DrxttvnPvLost88k7LxT1t3\m9aXk7wvEqQER5gSIZ4MeXVaOpiC6tCY8X9SXF2Cc6W8\G8cjovyGloJYMGVF9pvcMDXnafODPpnjmgiRqZkaX2sRVo\TLpvrkrdh6k9QqmTp\Jgdd2jfSHvKx3dr63eNkSoHd2vvf+nn\llOSXNlUDFyizqorDLaXgVawacR4UkrMDprx6vV40H4CJlEZXYLNFbi4B7OgPzEjkdh6bXc8jgwZM0dZ7nQVCS3qR4KaJt1IfXD26ZEVIYMUtsUy8AmzvlpCoXm3L7zCzmpjMhFeREt\XLPizAxb+gNHUpbX3MeRVqyWOEnNwCQKd12Nni78voskbJFRWbQMFNOBcvkBowfZRI7S7Z8\+qUMfQl6BFzt5bjLaGZPC3n6fvmkmW4ktLEY\M+RVKBfj3srgu3Kziw\IFCqGeyyyK3BwCUpa5ATJh9lFaXnF3xWVMG+dmVFefKaSyt0EA1Ve\gu+UQrObp8yubS5WtPjoEj35iAQKACzOqi9gocWPBZaWI19zksSZch57ZAJA99Nm80WOV79JOkBOFG3XWbbZ\NMWTNFLmKrxi402utkCuqGLqjyO8wU0PxQVEENK4RpsKp0hbLGC8Rix914E+jZTX2CkFklqIKtjbrhnjTBwKr3OqthG9vB3rmVJfnVpcV1pXVNl8h4bRXyAt9NcXB1B6x5pXVkJXSRNjGbVvGwoz+wNwxWJS1Xq42Vjt5yIc19JwzBonqQrpk1roE1OjwoJFq19s8QBCWteG7FzoOPbNhC8TL+tutj7A9SFBpQS+sdzvXJqqNJJi5uaamRyvkKuLGtngxQ2i0X4hqQGbu5sur3c8sfoIgVaO19tOXnNpuNOa9VQjV1rvd3hbXYx9NONTrXTBrGp61zwvVVBQom4xsn0HPzl2PGgEIaMEiD0HC7vSKJBXu2zFCIx4m2rjlbU0t937BdYGVGS0t7I2dkNVodJ1b9\pDzSru4AhOriYteAsWk9YsQ42DAzn5qjzanXkDISnqRILA\K9ZWPLuScHCcsc+JdiMM3qPFxraW79hH5siOS0jAnVPgpm3RSum6GmnObzecqaDavxLWb8kMXXxBNRNkcRuvYNIJuPDaSX5wYLPZmVxBoWIUJWi\koVIrcKmTuxPFbe0UG25KsoIQcE2qiZcWRlOOTT1O1XuoLZioJkr8AoWv7ljTOJ1hC8J15uoCsZ3eaF2A7Ce93m+jHpxJauPVTl7O2RCtsgq7D1er5cDeH5uvAaWDwwvrkqm0TWfz6ew99DyyrCw9kROKTb7m3bkcV6rBofIl3l11LCy\ajV9DgY5oATegVzkh\75ZgxoP57\tqNZBHZu+fMW\Gu6CDBq7rG7Vw3RWy63nUd6xFQ\V5KEFUTJBt72xXXSn84nzWxWW\Rba4woiG+XVoA7HYxTX9QkVmWfMlgRIot7IVN4EDW1pD20wzp6kdhwhFwHX3of3ctjJg380N2S\z6m64afyYxOtA1U3y+lfJVllg4xISfvuHdczPEXDLf2ZVBcXtyqwspe3vojA7mPgGbWKBWAVLdcZ2GcdZc6x5hRHifEKtvY\VIk89oEtquQwSXvPrhB1qO\F5b1dPCU+WfqHi2NnitAuVUsvVTtDU5d1na2qxw60JJ2FAEDRl2syCanw9LVtxbsK1+8SZcQkJiRMmLnlrJ6i8ZZIj++jjC37Io0mIwRVT5LXRzNJh2D9LYe5m6M6iamoqa2qqEgga29oEXV1dYeGVrOJFrGCxuA5fSkv6KXOmrPn0xXq13Wdw+f97KiM1NVWMWMjW9cJ68bGzxbk1Vzvr0g6HWbkmBR26Qri4PvncC5n1iiBDm0Ccu3K8tecIdGXuJpj3ybBSfF7y\JySfLLXg6ukyGlsp75XdTIFE14R1wBs97BFFsNuudvtDj2vZCmFUrmK7aXIZnYWNnXm1wl1jkFw5aKK+tTU1G9Pn\kq7b+pVxsicGcAAB6hSURBVOzgx4fOFZYiFq\B5W+Ran\MLdx\6LP\HPuytl2KuAZaNDSni\u+ShuXkLD7xJn0IsG4kQ2EJ952O4oySCoIRkG25ACr7JjE68Dk7yff\TfzEbWLly0JnCau6RnxevI7zGcqy6nvFe08I6yUVpegtZYbsjxeQ4h5NZtJFzkOo0QDd11Sy+WiZmluZevVD32jO+2\p1ID7JNPP0tNTd23\0CHwniusBT9+v6PDirtvUpHL\V78MOlUgiCxiUkPIYZ4zZ52ow\b\sA6yoUXMnb4izqsjCGviz4BLg16T7gzjJvZzR+wnic\41rbH+eTzOVhEMnItju4YysVkvzKc2OV6mcOH9AaXSxhRUYdkZXq8Z+Mr\69MV6dGXtUBg\3LMHR+qRYyekOofB5ZfqHD+ePbdv\4GqxjbsAzLzSxC6eRsZ5cVPrX4egqD\+Z\gSBo+l2z\7brY8LMa9ALNiqLK1abt++54abxEATNeHzJ4jd3sKokW7xsCRhkENjijvZYi0Ont+CQpVliWfJKEsmiSHChNqfTCUhFM1wlehcK6779BwJX1tTU1LT\ntLafeBhAon68Of\OfLFCfS7ez\6uKIDpp1ndDwrB4KgSVOnk3VURaVyc\RiQ3j0VSC0ZNYrwIEtBEGg5yF10ABrM+6cWSNqxy32tMcEGXSRLArJjBYOviwM08QNqHh1uz16g0EqV0nkCBmpQDKFii2pPp9PbzDIFKpSnhQNS312\Jv84oq8ovLvM7IOfnwoNTX1s\8crRNIwKc\1s4VlmJ9hgsXy7Hf\fzb7OzqRup3IqO8eNPb7zOpZuG2xIap43F6kWDNn\4K1lpWNnnaDFw1RE5DK9mdOZGdsevwx1\lZrLtVDzCu9Pp2W65aGtmSHlFuwsykZ5xP2Wz2dIph8UKDVoUrjR70YwWvqILsXhLq5vzisrzispLq5uHN3M6B8AXa2CzBVTDE+7bvx\91sdHv6EeuQFEkb4d\BIbvnbyYK19a8+ROeSFZYQGtpjDiyv5Tit54dUhYTePn5CQmFhYw+eGbLuklTmvra18Wn5Cw6tSpdYbDIGCEU2nHO6Uw52wTqGxkv14MV8GDgUonqJOIMHxyhONcKYzc\PBPux07sX0giJaWDPKizMry\LaGKVdszo9Ct\iSgju5u17fvXUqnvuY9T0feJtt6cXCQqEFooEwn9+mPrAQ1cb2GxP3ct5iWXlyFqt1gjxGqSUFu+xs8WnL9YTfhexeE9n5u7evRvHa\aFi9iHKYxuQHC9RM28uiu7rokJFqxO58O9uBLK1O9slreDIq0Vz65cvGwJWQ+iSVOn7\4y81+fH951+OMDXx8P9ATW\WXTpCmT0cf\+5PPOPMKHFkmsDY0VNLCGiu8Glz+nKqWzLLmwK\Xt3Tu27c\lcjS\nsq8PE65+D5uhqGsAIRFnkHw6uxL5SL65d5daChAWixQfiYkk7Sl3cy6\SGN7YBzyFpdtLCxQvXbVy3fdf27bu2v\nOm2tS1ixcvHDeg\MW\3rZur9sOvD18bS8nDXrR0xP3n3kc+ZTZIm9gs52Wl4lEtFo4lXW5QnktbFVhl1WP\vPUWyo9au0\wZep1ZCExYI1NnqauqigwKhpUHDwh9g26CTQqcqRNRZjhNvu\2T0z8Viqy4dmDtGunmra+Dx8xLnvfq668eTT+6fdf2NSlrsNrw2obUj1LTM9LTM9L3frp3TcqaSVMmP\jYo+j1wSyu4paWYHhVWl24Hls4NTeXMTzMjxVeDS5\qUCO\W8HbPpwz16A5pFjJ+oEEvB1cDwLXFXcFcR6O1tYgQIzYDjzKnM6Qri4Bo6gJ7QjWeXYc403\99bCYmJY8eOXbVm1fsfvr8mZc1tk26jvsJtk26blzxv3cZ1c+bM+emnn6ZMmQJB0Iy7Zv3zw1Rwi5gPPiYUXdphLRNYY4tXidGD\e+xE18DKHH7qg6FkZBXrcN3jvEUgwCVXGhBKLhh2Hg1tLBm1iuoF1dgIHcbzAuXmtWg9VDS7KQ1KWvmJc9jgjvWUlNT\X6\QSbdv3\nDlzZj9wP+hNlFV1ib6bNrkU5m4KXjulktHH6wj47L7dH36YmppaVEGwCUOX2A6FEf1iswLhCmtxRnnxmcoKCq+ACa\y7lDCynxxBXMNalXWZnn7vOT5EARdf8P1199wPVtSgUkkEq\dVvL2lpaWlsTE4dnhyQsXHPnxe7aDDpl7sfwWXkR51dr6pIgBhK60Wj0az0LDv+DoARwQSOQwdrrBiOs4h09ia3hCQCQ4esVJqnOgR1\Hv\wGLMCIrTezsjQYZCliBdg2hoRSuR0c5iBQi8niCkEQCKnmt+oJAwKPLlkBms+9fzjt+VfWYwNVgTZr1iy\39928oQ489SiRSOqxyZNmXzoZBrDSRvEgQJDF+lJAa86orwaTYySF3HXV6qQTlg34lLdw\48ey5wIgVVo3tcuwJAjju4rDZwomsGpF6xEU4YCXLysXZxNtuB49\8jn82O+XN6z\rqgefDevTZ9ZVYn+muv+sumGG28MvNp7773HO3qo6O+bjh8\HvjdcQkJuWW1nHlFXAMt5LW1TJIJqXj1+XxKFYI9iKKQXMl9xK3T6RQrNGjnGF33oMHl\+TTz\btP0C4uGJ9hryicpTazNx8nXMwo5xLU50RyPKkgfRQFEyHA9YCunoy1GbPfeiDz7\Feg7jJ4zfvPX1OpkUzRbI7zBjy19f3\4O2dX+88JvMlYtrTq4G\UEcJaQmPhtTgFnXkWwgoxXKTMXllG+i1arl8gRirYDnezzB3BmNltAZi1i8SIW74d79jS2y2n\ToA6FMbC0ursvIvfZeTQDufmhizZ4IAwwXqqQoTLyiWzlE1\v3nireDfN9508+5D+xthBFs6lt9hzqq9mqr26ltbyS416brEjFVLM1YtfekhqhTbYI5n5SYb+a6rngkn7PKzJKErLgg0MGJOYXT\54vj5fUtzL0RoIqmji9O5Rw7W3y6JATI4jpvEuYPhAnWAqFl8\Y9TGCdNHU6+u9Zsx8o6bSi\QSG1WHCwkqxskIQtGrWtIxVS3ctepD2eW8eP4EbsipnL1kgtrGpggkkoemvrbX3cUIUb263R6a1aO2+Dg1xzRaZFF09py\Wp12oPFVUVyGUBc9rxshzL00PAa+cK2BpBUq6ae2ZF18B\yBsm4xzA3Z8tJf6au88+kD607+akDCOyVNzRpYiSmAw0E+SYcerz+cja1HIYctFaKDfkdx0+adGifpKkiu1GiR6MD8x7UJlu86J0LUgYKgzFSXn+XLw3usDpnaFMBcbp8x6BUNn4LV3d0MQdPvUaYG95\Pa9Gdr6tHf5dNv0wg3WFhLf\pXi6dOwn5lwi23\GPX+9NIZs1NmjylRqgg41Jq9mzbsSvllY0ZBWXYr4tVMBmvbW0CWjxY12+RJcJ2hqhBvd\vN5stWntfZYfqu8JasuJYdFnNvpLo\XXuJXRYktjkDMkSm1FefJ4vKxBaAhfXBk24MloYjn+fk\xYZr1iTvJjgVc4L1Bim7mm5eXMuoemDfKsm294\cERGV5jx4378IvPa6RyqdnzwINUUbCke+csWrps0dJl23bs2rZj16HjaRkFZQt+9URCQuLew1+0a60Mo1qNjVW0bLDmlaylZkhcWNSkcpXWMQjaFKdfqDhf3d4sM3ao7UB8RVdhvRjbguBETilYWVHVSOUX+fwaqRyrFo2xXW9t11sv8vnMkc2p5xt6R8Sz9OFMF2QYGXho0ZN\3vZBYI\v3CZ8bfCCJYtpr7Zg8q03jB3RleOfH6bmNdahAdftqTTuBI7glzdsWrri6UPH03BuA2zvoTjook0pZM2rzUa84CmNrpAMVAAGZnvUSXRM+rsEtiRiItqab6xKWpsQd1c4MlrwtPF1DJm4\6EFEAQdOHnu6o+P3F0BHfiaIJIaaGNHDkRe95dNGeXFQqN9hOuptW56g6Y57qTJUw4dT6O+8xRRWB6vnMdrcDodZGBw6UdEFtgK7aRQpQrRu\zUzV8JWxQyV5WE3c6sQSkCvJbJwrW4phcJmOAF+hOuf+NddJt1ni8nbOi+46O9Y8cx2kKh9vuUlyluWo1QkfLKxpvHT8D+SNK9c7an7qVwZ0dwz6jogJhaLryStczohLn3SQw0r9erNLqEum7q\q\HzhZXCdXceEUYNNvCqaC5rtUQ1AAjap2qEIFZBtT21p4j6I\ktekpGmCdyM5gxevDCx6XMp4xUVjDZ\5gVEJFJwNeianlwivF1LhQRQmAgfLxn5o7KWBNu1AZzJhPxDXQrNKyTTzIaWgt6DCFj9oPPv+Wglq0mWZ+u4GiZhBoVcqLzGGdPnNWs5z7WD+GkqjVjHkt5\HKsUhw4dXt9pDxyrD\K0MDvrK86zIIV9H21+asVl0Xh1yZrNqGvDZt5Kl98rkXAKm01djfF+VPuOUWhrDePH5CGY9g4kDIRREiCAuvZP6AgVl\bebm8\lA9kJdJ+nGCxcW4CyxycktvetsTS2IeUWM2g8O\4eWVKBdhxmFxoCNHTt2waJFew9\Ee4lVml1MYe1ubkMi0TI+hOGaYlFT4BPFdUHwnqqqC6E9zGYdMQzleU5Da3hW24\+Cz95ddef+KpFckLF3xflM\wVa37yybmvL694+30jPQtW7fMuvvubTt2cXBMGQq2e5jz2tR0CcsDO16ZDJNXmb0cemmRmd4wfDwhItp4Ydu+BimJuZszrFhlVlXl1AvO8aQhYLfDdKFFldvUQTtcgEzLfvMMc14hCFq4eOH7H76fnpG+JmXNzLtm0UamYp1X6i4vqGRqU6hisdj2yBebpDhesT1fg1SrriskvOK9herq3KaOCy0qhvheaFHl8iQ5Da1nqznX9lzVHTNnkH30U1A7c9bMvZ\uPZp+dOHihctWPos7oIowr7g6bxa8kjV7I0Y26AxD1NBiBNjSi914cQ67EoptYIubzlSUna2pP1tTn1XXnNPQktPYDv7LbXYrrchyBtakrKFdax9e8PDeT\e+\+H7c+fP55xASCiGHQmAcE1fWMw7Zj6ME2y8mDcpojbsXHDsiVd+oyiEN5F2cNeo0\dF+YQgjp8w\mj6UVpewTKcsi7laPrRNSlr9n32RahudadGy8wTKEMQFQ4Gpry63R5WvIIT2pDECuTKEeGIvDoh4LVGElSFMU7n6uqiTlho9em3aWQLZ+pHqUx4Rfnevmv72zvefvq3vw9J6IDJeUFzczVhhQwLf4Dh8NgRXoHWwnlyDWq44wndlTyYZrgrVLC265w\lHEZoBzL2rrzfwn5W7dx3bqN6yAISrp3TrNctz1176TJU2ip3fDahsMnDs9LfojhoSuFWoVN1BsskaiDDAYWvPp8PrK6VgpJEUOQyKIhApxXgGYPBilJlzvtQmW46Ym8yKoJDh45CPoSHEk\jd6EQ8fTqJMGIQhatWbV4ROHkx95NJgdmMrZT+WtCnlKmCoeyi4+EIgOM8fAEQyyhJW6Z0uDqoW\+tlk7D6ZX\1VbvTxCrlSNv4pkLmZs2amZ6QnzU5KSEwMjLBmFJQtW\ksBbLLVy7fvmv7oqXLON9w6sYZcpMNRqimH4ZsPkxYHYPAoG97Jywdme3GGdZjZ4tP5BSfCkXVV0yJMHNg1ZpVez\dC0HQpjf+QXZbynjClFc2JpCUyAJ3Yu9hjtsvis2WoLUWcQ0oVFS11qx5ZXJkQIys2sQZ2cC4b6ccNppMTIYkkqlRbsSlJaTnF\3IuBFnIa+5XW9tUMCsUr+DV1bVpZK2tmaVtkVjPF9PdY6weMXyQNpAO62ExETanVOzXLdtx65A13bs2LF7P927YNEibgdgFI20hIrO0PPq9\uVKkSKGFCJFcNNiWm9W4XGyu3oC99Ww+VXqhA\+UQkWpW1KohHe2YXffsTDTGZFaW4kVSws79FYywXiqjn1AWjvMa6KokMl0ANO\spUngDW7mMnzD+y++\nHrHVIrFFSep2XPoeNr0mbNwTsWWrVuYXwQris2W3GQLC69k5vV6aZFVmb1KyhdEaJKACcvoRYSIntX9gh39JS1y6oTar3KLz5D03ciqqhBS+iFSq7tRqS5uaQmyORJ2KaVuvyo02rNrCPaLgZlZa1LWHDxyEIIgDvH\Z3434ojh7R1v33PvPWw3XhSNNfmC4cFJ1PknoeTV7\d7vd7AtTBQEqWWlW8QOBEc5dXt9sgYfzCBkUm0BQtny\mwo79OpsCNpi9r72A1f6JV11Up6qSeb0+oSlEn9V8FngNHb2B5T6AzcPjE4ZR1Kc\8bg2HdRFXvzVz1swNr23YdeATVheh6O+CDvAWy6lGxISYV7\f7\P5mCCrNLqYn9nijgywvPr9fkRDf3DQrnNeqOtgUgp2qqgOTQCX2y6D0vCsqkt8lgs5KmbF5VcHLmRVXeL2RK26LrDQZlaWfns+Dwdr0uyko+lHx08Yzy3JtVmOLyxbt3Hd9JmzWF2EonJLZrREh1c\Y2RBqEuuRGiTY5QqKl79I+fO4SS1XCbzVglhxY6mRzkIpiF6nUzBanHlNqIN\QOrFHXKbZczCspweG3ZumXdxnXLVj7L+eK4AO3UO6bOeWDOVz9kM\xxikgWX1CNjpqPAq9+v9\n8zFM5gJOrUQOUxzearV6al59Pl\g9ORGuREdQ8cZ1uBFO8wWu7hmlBfzVEGdeR46nvbM79bg9vVPr3r68InDY8eOxXWvYKVdBz7B\Q3MeWBOyisbGf44RWSgQ3Z1yY8Or36\v5PT+a1ShZjNFtylAs8pAjdtNpsNhLfadc4ivgzbnYCJTuZXhwNWxDUgt12mhHXEOfCZ8mKhUsHhWaRmz97DXxCeUd026bbUj1JnzprJnC1CtWutgUHZqdOmM\lZ6tHdLW310edVoiQtS6SVQmPtVKiUKsRms\uJjrhwvHq9XkSjbVNq2WKK6kxZaA7MCEW55RqxuJ6vKuULKlUs2wIX1vCT7p0TSCoEQWPHjk39KHVe8rzpM2cFXzLw+5SXA6\PxCEWKWXUCS4yQ1eUeeWQbEC26EoRo8E94otihbZTDoMAsExtQr\Oh83ceP2hpCF8vFKeKYzgtaSulMcrlyAqhlfOKCh7eMHjhKRCEHT9Dddv2bplXvI8zu3ZAv8wAp+F9qxL5eylnRrX3tkeZV7Z5h+GSpUdKg68nsxnPTiduSpFnYSwninHJ4XVNV0Cn48qJ71zcuh4GtmpKYD1\Q\ff3jBw6GCFShwiaVNJ6BdXIFgew8SyfMCrFHUfEdA52raYopXscmJ9vD6qaHmfFXp+arSc1Wl56pKwL+B8qtLA9cbQknNHlwAn3BlnXrH1IcXPB58BiBWzXId7o\k5vETKDwNhbmbevgWKhGsQFwDIc53YWhGU1cUedU6Bn8oaWCLbPh4RQXbexi+eej5ZKDatVbqLKqpd0ydlzwvITGRbTyfoV5\ezvuGSn+JJiPPBa01qqc\TrKspRw8RoYMQ2x3DQPUFq8IK07pnhl+MmI7poDvYJ2rZVsawVB0NixY6+\4fqJt0x8\e3t4WsjIDV7cPEysjkcbFu5SHVGm80WBV59Ph\DeBbF3O4g1a5x0PbewipUCeBkYrW4knkF1CvrAw8mR6DhBeIa+DanAOsVbNuxi+j39bD9fdvEAuqMqDDut\x+v9lswW7e8Z\a9j5wJOv1emFEI5YjYORGSJZYmdbSqVC1SZWIa6BGoqXoaHTsbPHXuZdC2MqATBStpSkkVl19YYERewiCJk2esmjpslde\Wtoq1hphc0oCMxJUDn76fpmEkunp+oaGF5egUnlqsBYgUJjBbFVnJnNFqlcRUE5hVRmr1ihUaoQ7FGZUIEgrgGp5TJZa87Cps4wnRTgRJ1aTyEQmzx3qQ7tE5+QmAj6WX\1Q3b4GrHQCnVkJ02egvsW3cBYYjU1V1AP4ooEr36\3+l0YjMKJHKYNmcALLoUQ5QMLr8Rc8HAUzFgPp8PzTksa1VgPYQzZc1CY3ck32Amk9UJte\QIUDGK5s2R4vOQEnNnpRXNoIXNvwLaq3V7XKhXMzt12zr7KSmIkK8AlOqEIXGqtXSjwFBLTDzdYS6h5dVavq9Xq9EM5ypKTR2nyqqO5lf3SjH5xtEQJyX2PqGkid\vYLwkzfqAsii9Qh5RfkcYRULhAqa3OiI8srBAjMJAyWW0yeAO51OtN4LdvQH2TI2GHFeYnm88o2v\SXwkzcWtG3HrqUrVkIQdPCTA9x+Nb6gErZ7qA+3\LHPK0UcV4\u25gt2FhkoyuFuVuqM4pVcJtYQHtQiXtT\zc1NeQNrUKi+x6Y+382rOf8pyhRqxG6wwJ\7POK7fdGGBygdQawFjvIYqVy9spNNgmiEsrFFElMqKQ6jpnj4ZPC3F1ccp72lQtaa9vEApxEsALNlzCaTNTvYKzz6vfTBGjZzlGy2WzM62ei8sYzQbZDJmSSYBAZSdRqJp8SLW31sJ3mztNWSY0CXjsVKpCHdTVWgIm8wgjruV9msyWYQvAIIMskcskXVJMd2EZMsN3TKuQx+bhnAqvMTN9tbRTwGg7TaHWxjCxs9zAMtrd3tkdroZUgKiYfBQxhRVwDQiTU82OvJYMR7lOQYgpZvqBaBCvgCP75SXX6NrGA4UaKIawIXeYrsJ8vr36\X6FCos5lSJDl8cr5gkqRUhZWalXOfqlOz+qUlTmsiGuAOjML2M+aV7\fDyPqWHYMOJwvtAqbQh5AkBktHTIhq9AbW1hlZg+TOM\PnVe\36\R6mI5YsCWV3S57ZAJpTo95xVX5eyXm2xCRWdLeyO318BqO0h7sgUszqvfD\LIYhVZhnsayhWXJ5SLJWq13GSjwBe2e+Qmm8zQBQ4y2KYCBor54oq4BqQKRmOw4rwOm81mi8GjBIR+mjWXpbdNLBDKxSJY0Srisz1jYy5WvyZ1mjZqcV6vmtPpDGy6EXUxDHDGmrAtBWjFJJIFLM7rCPN6vbGGLPP6J47LLT8sl20V8pj\jrRpA6jFecWb1+tl26MzrOKcSxpdYVsMUUth72HerDLOK4H5fD4RrIk6qUAUPShjeYkVKWVM\yAZOwP+OK9k5vP5QCFN1CVBVEz4aBU2hWnbxE0gP5CJZEoV8\clziuVce43H0IpzA7qkJZQLlaYu688uFuCqDhs0ZqbKRdgQTUazQWnXLRPgfZzpfnt7D2shgrGeaUxo8kki2yNV6Bge09gVYKgtZYibUDl7JXqjEK5OJhFt1XIkyAqhdlB+BRKq0uo6Az8W2oV8sh+JFAMjwlQi\NKb16vV6iMfnKMzGgBsdiW9kapTs+8hyFYdJkfUwnlYqnOyDDtC7vc8gXVzDvVAZFViZJZnFemJiFv4R0xqZz9zJcunBh266Du20UhpdXF9uxXrDayfRfivLKwGE+OoRVFdyDUf0Vd4QhIo6VqjUFocV7Zmc1mQ0vDR51Uzn7qWcOtwqZQ4ugeMF0eNF0etPcOOvuGcNKbrTAMwzCs1+sNV4z2\sd5ZW0+n08kj4lQFwfJjBaKxRVtcs1Kes+A1Tvo7BvyDgz1DgwFeXv7+vpUKhXZd+O8cjSZUjVKfQOyBgignSWTK5guDzr7hlz9Q96BocFg+cSb1+ulaPkW55W7mc2W0egb4DZe6OJKHeE3eAadfSFYPmlNq9VSfDfOa1Dm8\nEMXCmwFadGi2m\F8p1enlJlvg4qp1D1i9g+7+Id9ghO4nDNNkwcZ5DYEZTabYzJ3lLEvPoKt\KOxr6UjT6ejDBXFeQ2Ner3f0bsJQadwD9t7BiK2mWHM4HEyytOK8htI0Wl3UD2+5Sese6O4L\eaJofX19VksjA664ryG2EbdQqt1D7j7o8TpFUMQplkEcV7DYhqtLtbqFAKlcQ84o7emoka7x8JanNcwmkypiln3wOodjDqpfr\fZDIxby\pj\MabvN6vRSz7qOlrp5B78AQodz9+INTJnL0DoKj10BpnJdhFWIgMeaVMMDivEbCjCaTWB3r7kGYxCGphcLivEbOYtk9CJOoh8FysDivETWfzydVwDHbSyaUpNp7QruyAovzGgXzer1iufIaplZm9oQDVn+c1yia1+uVyOFrz0MQq2lmwAZjcV6jbwoVcs2kHwgVCKv4FFuL8xorhmi0sdOkg4NkZg\DHoPBWJzX2DKn0ymSj74NmQjWsGojwNnivMai+Xw+GFHHSIMZaom1Rubd2oK3OK8xbW63R6ZUxWYqglhrZDJxILQW53V0mNvtUaiQWGjbgbgGhIge0VBVrYTP4ryOMvN6vTCiFsnhyJeOyYzdQgVCOzIzrBbndRSb2+2BEbVYDoc1OUGsNUoVMEXNaiQtzus1YmDdFcuVYrlSqFRzjjDIzB4hohciepEchhE12\ypcFuc12vZjCaTzmAY5lgBAxBxEitgqQLWGQw69tl9kbc4r3EbTRbnNW6jyeK8xm00WZzXuI0m+\8gZ08fpVj9RQAAAABJRU5ErkJggg== (El nombre de archivo, el nombre de directorio o la sintaxis de la etiqueta del volumen no son correctos)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at sun.net.www.protocol.file.FileURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.file.FileURLConnection.getInputStream(Unknown Source)
    at java.net.URL.openStream(Unknown Source)
    at com.lowagie.text.Image.getInstance(Unknown Source)
    at com.lowagie.text.Image.getInstance(Unknown Source)
    at com.lowagie.text.html.simpleparser.HTMLWorker.startElement(Unknown Source)
    at com.lowagie.text.xml.simpleparser.SimpleXMLParser.processTag(Unknown Source)
    at com.lowagie.text.xml.simpleparser.SimpleXMLParser.go(Unknown Source)
    at com.lowagie.text.xml.simpleparser.SimpleXMLParser.parse(Unknown Source)
    at com.lowagie.text.html.simpleparser.HTMLWorker.parse(Unknown Source)
    at com.crc.tecnatom.gaddie.reports.ExamenInforme.imprimePDF(ExamenInforme.java:61)
    at com.crc.tecnatom.gaddie.controllers.ExamenesController.descargarExamen(ExamenesController.java:114)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    
  • jd.carretero
    jd.carretero over 11 years
    it's not as easy at it seems doing it in java =(
  • Mr code.
    Mr code. over 5 years
    I have followed the same steps above but the image is not displayed in pdf and did not get any error.
  • Delush
    Delush over 5 years
    This worked for me.. thanks mate!
  • Cyril
    Cyril about 5 years
    I followed exactly these steps in the latest version of itext (5.5.13) and it still works like a charm, thank you very much !
  • Mahmoud Saleh
    Mahmoud Saleh about 5 years
    It worked perfectly with me with itext5, but you have to make sure that the image tag is closed correctly with />
  • Glyn
    Glyn over 3 years
    I wan to send my output to a table using final InputStream is = new ByteArrayInputStream (ppDescription.getBytes("UTF-8")); xmlParser.parse(is, charset); and Paragraph p6 = new Paragraph(""); p6.add(element); cell.addElement(p6); How can I implement this please?