0
public string GetPDF(string pHTML)
    {

        byte[] pdf; // result will be here

        var cssText = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/Content/bootstrap.css"));
        cssText=cssText + System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/Content/styles.css"));
        var html = pHTML;

        using (var memoryStream = new MemoryStream())
        {
            var document = new Document(PageSize.A4, 15, 15, 15, 15);
            var writer = PdfWriter.GetInstance(document, memoryStream);
            document.Open();

            using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
            {
                using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)))
                {
                    XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlMemoryStream, cssMemoryStream);
                }
            }

            document.Close();

            pdf = memoryStream.ToArray();
        }
        var temp = Convert.ToBase64String(pdf);
        return temp;


    }

I pass the html string from razor view to controller but image tag closing error shown when XMLWorkerHelper try to parse and if i direcly pass image tag string from code behind then no image shown

Jas
  • 61
  • 1
  • 6
  • Most likely the problem is in the html/css you feed into the `XMLWorkerHelper`. Please also show these data, in particular those parts responsible for the image in question. – mkl Apr 26 '17 at 04:49
  • can i export data:image/png;base64 image to pdf? – Jas Apr 26 '17 at 05:47
  • Yes but you need to use a custom image provider. – mkl Apr 26 '17 at 06:13
  • can you please provide custom image provider code with above code modification?? – Jas Apr 26 '17 at 06:16
  • A very popular method for iTextSharp appears to be to actually extend the image tag processor instead of using an image provider. You find that in [this answer](http://stackoverflow.com/a/19398426/1729265) to [Can itextsharp.xmlworker render embedded images?](http://stackoverflow.com/questions/19389999/can-itextsharp-xmlworker-render-embedded-images). For iText/Java also finds solutions with an image provider, e.g. [here on the itext web site](http://developers.itextpdf.com/examples/xml-worker-itext5/html-images#1512-parsehtml4.java). – mkl Apr 26 '17 at 06:49
  • Yes i test this code but i dont want to save file into local system,In your suggestd example it save file in local system thats why i need custom helper use with above code i posted – Jas Apr 26 '17 at 06:53
  • 1
    If you don't want the result in the file system, don't stream it there. The referenced example uses a `FileStream` but that cannot keep you from using a `MemoryStream` like you do in your code, can it? – mkl Apr 26 '17 at 06:59
  • i can't get what are try to say, I just want to use Customhelper with above code , i want to show file dialog to user for download file for that i need byte array – Jas Apr 26 '17 at 07:17
  • 1
    Thanks i just add using (var memoryStream = new MemoryStream()) {.... } and it works – Jas Apr 26 '17 at 10:55

1 Answers1

1
public string GetPDF(string pHTML)
    {
        byte[] pdf;
        using (var memoryStream = new MemoryStream())
        {
            using (var doc = new Document(PageSize.A4, 15, 15, 15, 15))
            {
                var writer = PdfWriter.GetInstance(doc, memoryStream);
                writer.PageEvent = new PDFEvents();
                doc.Open();

                var html = pHTML;
                var tagProcessors = (DefaultTagProcessorFactory)Tags.GetHtmlTagProcessorFactory();
                tagProcessors.RemoveProcessor(HTML.Tag.IMG); // remove the default processor
                tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor()); // use our new processor

                CssFilesImpl cssFiles = new CssFilesImpl();
                cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS());
                var cssResolver = new StyleAttrCSSResolver(cssFiles);

                var cssText = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/Content/bootstrap.css"));
                cssText = cssText + System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/Content/styles.css"));

                cssResolver.AddCss(cssText, "utf-8", true);
                var charset = Encoding.UTF8;
                var hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
                hpc.SetAcceptUnknown(true).AutoBookmark(true).SetTagFactory(tagProcessors); // inject the tagProcessors
                var htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(doc, writer));
                var pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
                var worker = new XMLWorker(pipeline, true);
                var xmlParser = new XMLParser(true, worker, charset);
                xmlParser.Parse(new StringReader(html));


            }
            pdf = memoryStream.ToArray();
        }

        var str= Convert.ToBase64String(pdf);
        return str;}

And My client side code I am passing xhtml to mvc action method

var doc = new DOMParser().parseFromString($('#content').html(), 'text/html');
        var result = new XMLSerializer().serializeToString(doc);

        $.ajax({
            url: '@Url.Content("~/contoller/action")',
            type: "POST",
            dataType: "JSON",
            data: { strHtml: result },
            success: function (response) {
                debugger;
                var sampleBytes = base64ToArrayBuffer(response);
                saveByteArray([sampleBytes], 'test.pdf');
            }
        });


        function base64ToArrayBuffer(base64) {
            var binaryString = window.atob(base64);
            var binaryLen = binaryString.length;
            var bytes = new Uint8Array(binaryLen);
            for (var i = 0; i < binaryLen; i++) {
                var ascii = binaryString.charCodeAt(i);
                bytes[i] = ascii;
            }
            return bytes;
        }

        var saveByteArray = (function () {
            var a = document.createElement("a");
            document.body.appendChild(a);
            a.style = "display: none";
            return function (data, name) {
                var blob = new Blob(data, { type: "octet/stream" }),
                    url = window.URL.createObjectURL(blob);
                a.href = url;
                a.download = name;
                a.click();
                window.URL.revokeObjectURL(url);
            };
        }());
Jas
  • 61
  • 1
  • 6