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

9
  • 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. Commented Apr 26, 2017 at 4:49
  • can i export data:image/png;base64 image to pdf? Commented Apr 26, 2017 at 5:47
  • Yes but you need to use a custom image provider. Commented Apr 26, 2017 at 6:13
  • 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? Commented Apr 26, 2017 at 6:59
  • 1
    Thanks i just add using (var memoryStream = new MemoryStream()) {.... } and it works Commented Apr 26, 2017 at 10:55

1 Answer 1

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);
            };
        }());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.