【问题标题】:Converting contenteditable content to PDF将 contenteditable 内容转换为 PDF
【发布时间】:2019-12-24 08:02:05
【问题描述】:

我想知道将contenteditable 特征(用户输入的内容)转换为pdf 的最有效方法。这是我的意思的说明:

1.

2

3

我也想知道如何转换 css 功能,因为 jsPDF 不支持这个(据我所知)

【问题讨论】:

    标签: c# pdf contenteditable html-to-pdf


    【解决方案1】:

    jsPDF 几乎不支持您需要的功能。我建议创建一个应用程序来做到这一点。

    我的背景是 C#。所以:

    Program.cs

    using HtmlToPdf.Models;
    
    namespace HtmlToPdf.Console
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var model = new HtmlToPdfModel();
                model.HTML = "<h3>Hello world!</h3>";
                model.CSS = "h3{color:#f00;}";
    
                HtmlToPdf.Convert(model);
            }
        }
    }
    

    HtmlToPdfModel.cs

    namespace HtmlToPdf.Models
    {
        public class HtmlToPdfModel
        {
            public string HTML { get; set; }
    
            public string CSS { get; set; }
    
            public string OutputPath { get; set; }
    
            public string FontName { get; set; }
    
            public string FontPath { get; set; }
        }
    }
    

    HtmlToPdf.cs

    using iTextSharp.text;
    using iTextSharp.text.pdf;
    using iTextSharp.tool.xml;
    using HtmlToPdf.Models;
    using System;
    using System.IO;
    using System.Text;
    
    namespace HtmlToPdf.Console
    {
        public class HtmlToPdf
        {
            public static void Convert(HtmlToPdfModel model)
            {
                try
                {
                    if (model == null) return;
    
                    Byte[] bytes;
    
                    //Boilerplate iTextSharp setup here
                    //Create a stream that we can write to, in this case a MemoryStream
                    using (var stream = new MemoryStream())
                    {
                        //Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
                        using (var doc = new Document())
                        {
                            //Create a writer that's bound to our PDF abstraction and our stream
                            using (var writer = PdfWriter.GetInstance(doc, stream))
                            {
                                //Open the document for writing
                                doc.Open();
    
                                //In order to read CSS as a string we need to switch to a different constructor
                                //that takes Streams instead of TextReaders.
                                //Below we convert the strings into UTF8 byte array and wrap those in MemoryStreams
                                using (var cssStream = new MemoryStream(Encoding.UTF8.GetBytes(model.CSS)))
                                {
                                    using (var htmlStream = new MemoryStream(Encoding.UTF8.GetBytes(model.HTML)))
                                    {
                                        var fontProvider = new XMLWorkerFontProvider();
    
                                        if (!string.IsNullOrEmpty(model.FontPath) && !string.IsNullOrEmpty(model.FontName))
                                        {
                                            fontProvider.Register(model.FontPath, model.FontName);
    
                                            //Parse the HTML with css font-family
                                            XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, htmlStream, cssStream, Encoding.UTF8, fontProvider);
                                        }
                                        else
                                        {
                                            //Parse the HTML without css font-family
                                            XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, htmlStream, cssStream);
                                        }
                                    }
                                }
    
                                doc.Close();
                            }
                        }
    
                        //After all of the PDF "stuff" above is done and closed but **before** we
                        //close the MemoryStream, grab all of the active bytes from the stream
                        bytes = stream.ToArray();
                    }
    
                    //Now we just need to do something with those bytes.
                    //Here I'm writing them to disk but if you were in ASP.Net you might Response.BinaryWrite() them.
                    //You could also write the bytes to a database in a varbinary() column (but please don't) or you
                    //could pass them to another function for further PDF processing.
    
                    // use this line on Windows version
                    //File.WriteAllBytes(model.OutputPath, bytes);
    
                    // use these lines on Mac version
                    string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "data");
                    path = Path.Combine(path, "test.pdf");
    
                    File.WriteAllBytes(path, bytes);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }
    }
    

    当我编写这个应用程序时,我已经在 Windows 上进行了测试。因此,如果您使用的是 Mac,则可以替换该行:

    File.WriteAllBytes(model.OutputPath, bytes);
    

    在文件HtmlToPdf.cs

    string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "data");
    path = Path.Combine(path, "test.pdf");
    
    File.WriteAllBytes(path, bytes);
    

    我已经在代码中注释了。

    关于字体问题,如果你想使用特定的字体(例如:Roboto),你必须提供你的应用程序可以分配的字体文件和路径。

    Nuget 包:iTextSharpitextsharp.xmlworker

    您可以将此控制台应用程序转换为 Web 应用程序,每次您要制作 PDF 文件时,只需向服务器发出请求 (ajax) 并点击方法HtmlToPdf.Convert

    【讨论】:

    • 所以我可以使用 ajax 来转换你给我的代码,让它与我的 html/js/css 文件一起工作?
    • @dcnx1 你可以用我的代码创建一个扩展。如果您使用的是 asp.net mvc,则称为 Class library。然后将此扩展添加到主项目。我的代码仍在服务器端(C# 语言)工作。在客户端,您可以将html string, css format, font family... 等所有数据包含到一个对象中,并使用ajax 将其发送到服务器。
    • 那么每次有人在下载 pdf 文件时放入其他内容时,pdf 的内容会更新吗?如果我将它添加到我的网页中,即使我添加图像或链接(在 html/css 中)之类的东西,我可以把它留在那里并期望它工作吗?
    • @dcnx1 是的。每次您的用户点击方法HtmlToPdf.Convert,都会创建新的PDF文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多