我想通过将HTML内容传递给函数来生成PDF。我已经为此使用了iTextSharp,但它在遇到表和布局时表现不佳。

有没有更好的办法?


当前回答

PDFmyURL最近也发布了一个。net组件,用于网页/ HTML到PDF的转换。它有一个非常友好的用户界面,例如:

PDFmyURL pdf = new PDFmyURL("yourlicensekey");
pdf.ConvertURL("http://www.example.com", Application.StartupPath + @"\example.pdf");

文档:PDFmyURL .NET组件文档

免责声明:我为拥有PDFmyURL的公司工作

其他回答

我之前也在找这个。我遇到了HTMLDOC http://www.easysw.com/htmldoc/,这是一个免费的开源命令行应用程序,它以HTML文件为参数,并从中输出PDF。这在我的副业项目中非常有效,但这完全取决于你真正需要什么。

制作它的公司出售编译后的二进制文件,但您可以免费从源代码下载和编译并使用它。我设法编译了一个最近的版本(1.9版本),我打算在几天内发布它的二进制安装程序,所以如果你感兴趣,我可以在发布它时立即提供它的链接。

编辑(2/25/2014):看起来文档和网站转移到http://www.msweet.org/projects.php?Z1

如果你已经使用itextsharp dll,不需要添加第三方dll的(插件),我认为你正在使用htmlworker而不是它使用xmlworker,你可以很容易地将你的html转换为pdf。 一些css不能工作,他们是受支持的css 完整的解释与示例参考点击这里

        MemoryStream memStream = new MemoryStream();
        TextReader xmlString = new StringReader(outXml);
        using (Document document = new Document())
        {
            PdfWriter writer = PdfWriter.GetInstance(document, memStream);
            //document.SetPageSize(iTextSharp.text.PageSize.A4);
            document.Open();
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(outXml);
            MemoryStream ms = new MemoryStream(byteArray);
            XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, ms, System.Text.Encoding.UTF8);
            document.Close();
        }

        Response.ContentType = "application/pdf";
        Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".pdf");
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.BinaryWrite(memStream.ToArray());
        Response.End();
        Response.Flush();

很可能大多数项目将包装C/ c++引擎,而不是从头开始实现c#解决方案。试试哥德堡计划。

为了测试它

docker run --rm -p 3000:3000 thecodingmachine/gotenberg:6

旋度样本

curl --request POST \
    --url http://localhost:3000/convert/url \
    --header 'Content-Type: multipart/form-data' \
    --form remoteURL=https://brave.com \
    --form marginTop=0 \
    --form marginBottom=0 \
    --form marginLeft=0 \
    --form marginRight=0 \
    -o result.pdf

c# sample.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
using static System.Console;

namespace Gotenberg
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            try
            {
                var client = new HttpClient();            
                var formContent = new MultipartFormDataContent
                    {
                        {new StringContent("https://brave.com/"), "remoteURL"},
                        {new StringContent("0"), "marginTop" }
                    };
                var result = await client.PostAsync(new Uri("http://localhost:3000/convert/url"), formContent);
                await File.WriteAllBytesAsync("brave.com.pdf", await result.Content.ReadAsByteArrayAsync());
            }
            catch (Exception ex)
            {
                WriteLine(ex);
            }
        }
    }
}

要编译

csc sample.cs -langversion:latest -reference:System.Net.Http.dll && mono ./sample.exe

你可以使用WebBrowser控件的另一个技巧,下面是我的完整工作代码

在我的例子中,为文本框控件分配Url

  protected void Page_Load(object sender, EventArgs e)
{

   txtweburl.Text = "https://www.google.com/";

 }

下面是使用线程生成屏幕的代码

  protected void btnscreenshot_click(object sender, EventArgs e)
  {
    //  btnscreenshot.Visible = false;
    allpanels.Visible = true;
    Thread thread = new Thread(GenerateThumbnail);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();

}

private void GenerateThumbnail()
{
    //  btnscreenshot.Visible = false;
    WebBrowser webrowse = new WebBrowser();
    webrowse.ScrollBarsEnabled = false;
    webrowse.AllowNavigation = true;
    string url = txtweburl.Text.Trim();
    webrowse.Navigate(url);
    webrowse.Width = 1400;
    webrowse.Height = 50000;

    webrowse.DocumentCompleted += webbrowse_DocumentCompleted;
    while (webrowse.ReadyState != WebBrowserReadyState.Complete)
    {
        System.Windows.Forms.Application.DoEvents();
    }
}

在下面的代码中,我下载后保存pdf文件

        private void webbrowse_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // btnscreenshot.Visible = false;
    string folderPath = Server.MapPath("~/ImageFiles/");

    WebBrowser webrowse = sender as WebBrowser;
    //Bitmap bitmap = new Bitmap(webrowse.Width, webrowse.Height);

    Bitmap bitmap = new Bitmap(webrowse.Width, webrowse.Height, PixelFormat.Format16bppRgb565);

    webrowse.DrawToBitmap(bitmap, webrowse.Bounds);


    string Systemimagedownloadpath = System.Configuration.ConfigurationManager.AppSettings["Systemimagedownloadpath"].ToString();
    string fullOutputPath = Systemimagedownloadpath + Request.QueryString["VisitedId"].ToString() + ".png";
    MemoryStream stream = new MemoryStream();
    bitmap.Save(fullOutputPath, System.Drawing.Imaging.ImageFormat.Jpeg);



    //generating pdf code 
     Document pdfDoc = new Document(new iTextSharp.text.Rectangle(1100f, 20000.25f));
     PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
     pdfDoc.Open();
     iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(fullOutputPath);   
     img.ScaleAbsoluteHeight(20000);
     img.ScaleAbsoluteWidth(1024);     
     pdfDoc.Add(img);
     pdfDoc.Close();
     //Download the PDF file.
     Response.ContentType = "application/pdf";
     Response.AddHeader("content-disposition", "attachment;filename=ImageExport.pdf");
     Response.Cache.SetCacheability(HttpCacheability.NoCache);
     Response.Write(pdfDoc);
     Response.End();


}

你也可以参考我最老的帖子了解更多信息:在asp.net web表单中导航到网页被取消了

另一个建议是尝试https://grabz.it的解决方案。

他们提供了一个很好的。net API来捕捉屏幕截图,并以一种简单灵活的方式进行操作。

要在你的应用中使用它,你首先需要获得key + secret并下载。net SDK(它是免费的)。

下面是一个简短的例子。

要使用这个API,你首先需要创建一个GrabzItClient类的实例,将你的应用密钥和应用秘密从你的GrabzIt账户传递给构造函数,如下面的例子所示:

//Create the GrabzItClient class
//Replace "APPLICATION KEY", "APPLICATION SECRET" with the values from your account!
private GrabzItClient grabzIt = GrabzItClient.Create("Sign in to view your Application Key", "Sign in to view your Application Secret");

现在,要将HTML转换为PDF,你需要做的是:

grabzIt.HTMLToPDF("<html><body><h1>Hello World!</h1></body></html>");

你也可以转换为图像:

grabzIt.HTMLToImage("<html><body><h1>Hello World!</h1></body></html>");     

接下来需要保存图像。你可以使用两个可用的保存方法之一,如果公共可访问的回调句柄可用,则保存,如果没有SaveTo。详细信息请查看文档。