繁体   English   中英

使用PDFsharp将PDF文件附加到Mandrill电子邮件

[英]Attach a PDF file to a Mandrill email using PDFsharp

我一直在从事一个项目,该项目要求我通过Mandrill电子邮件附加PDF文档(包含动态数据的传真封面),而我最糟糕的时间是通过各种方法分类以完成此看似简单的任务。 这是我的项目的细节:

  • 这是一个控制台应用程序
  • 我解析文件中的数据并通过Mandrill通过电子邮件发送该数据


现在我需要:

  • 将相同的已解析数据转换为PDF
  • 将此新创建的PDF附加到我的Mandrill电子邮件中
  • 将此PDF文件丢弃在[本地]机器上

那么,最有效,最轻松的方法是什么?

我已经编译并测试了我新创建的项目,并且以下项目运行得非常好(我敢说“完美无瑕”或“完美”,因为我确信有人会找到更好的方法来完成我的工作)。 如您所见, 我将数据保存到图像中,并将这些图像放置在新创建的PDF页面上。


父方法

public static void SendEmail()
{
    try
    {
        /*
            Standard code to prepare Mandrill email. 
            'EmailMessageObj' is the Mandrill.EmailMessage object
        */

        //Create PDF with data
        Pdf pdfObject = new Pdf();
        PdfDocument document = Pdf.Document(param1, param2, pdfObject); //create PDF document and pass in object's data. Sets pdfObj properties, such as the byte[] PdfBytes seen below

        using (MemoryStream stream = new MemoryStream())
        {
            // Create email attachment
            EmailMessageObj.attachments = new[]
                {
                    new attachment
                        {
                            content = Convert.ToBase64String(pdfObject.PdfBytes),
                            name = "Fax Cover Sheet.pdf",
                            type = "application/pdf"
                        }
                };
        }

        api.SendMessage(EmailMessageObj);
    }
    catch (Exception error)
    {
        Console.WriteLine("Could not send email." + error);
    }
}


Pdf对象
我添加了对以下内容的引用:“ HtmlRenderer”,“ HtmlRenderer.WinForms”,“ PdfSharp”

using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using TheArtOfDev.HtmlRenderer.WinForms;

class Pdf
    {
        public string PdfFileDirectory { get; set; }
        public string PdfCoverFileName { get; set; }

        public string LogoFileName { get; set; }

        public Image PageOne { get; set; }
        public Image PageTwo { get; set; }
        public byte[] PdfBytes { get; set; }

        public Pdf()
        {
            PdfFileDirectory = Settings.BaseBaseDirectory + @"\";
            PdfCoverFileName = "FaxCoverPage.pdf";

            LogoFileName = "Logo.jpg";

            PageOne = null;
            PageTwo = null;
            PdfBytes = null;
        }

        /// <summary>
        /// The PDFsharp PDF Document. This creates images out of the data and then puts those images onto the (created within) PDF pages.
        /// </summary>
        /// <param name="addressedTo">The person this is being sent/addressed to</param>
        /// <param name="dataFormattedIntoTable">The formatted data table</param>
        /// <param name="pdfObj">The Pdf object</param>
        /// <returns></returns>
        public static PdfDocument Document(string addressedTo, string dataFormattedIntoTable, Pdf pdfObj)
        {
            //See https://htmlrenderer.codeplex.com/wikipage?title=Image%20generation for documentation

            //First Page (To, From, disclaimer, etc.)
            pdfObj.PageOne = HtmlRender.RenderToImageGdiPlus(CoverPage_Front(addressedTo), new Size(600, 0), new Size(800, 0)); //Create an image from passed-in data. Set Min/Max size restriction
            using (MemoryStream stream = new MemoryStream())
            {
                pdfObj.PageOne.Save(stream, ImageFormat.Png); //save via stream so I do not have to save this file locally and can then dispose of it, thus freeing things up
            }

            //Second Page (logo and data table)
            pdfObj.PageTwo = HtmlRender.RenderToImageGdiPlus(CoverPage_Content(addressedTo, dataFormattedIntoTable), new Size(600, 0), new Size(800, 0)); //Create an image from passed-in data. Set Min/Max size restriction
            using (MemoryStream stream = new MemoryStream())
            {
                pdfObj.PageTwo.Save(stream, ImageFormat.Png); //save via stream so I do not have to save this file locally and can then dispose of it, thus freeing things up
            }

            // Create a new PDF document
            PdfDocument document = new PdfDocument();

            // Create an empty page
            PdfPage page = document.AddPage();

            // Get an XGraphics object for drawing
            XGraphics gfx = XGraphics.FromPdfPage(page);

            //I only want two pages so..
            for (int pageCounter = 0; pageCounter < 2; pageCounter++)
            {
                if (pageCounter == 0)
                {
                    // draw Fax cover page (To, From, disclaimer, etc.)
                    gfx.DrawImage(pdfObj.PageOne, 0f, 35f); //fax cover page image, margin-left, margin-top

                    // since this is the first page, add a second one. This will NOT be done on subsequent pages because we are planning on only have 2 pages for now
                    page = document.AddPage(); //add the second page
                    gfx = XGraphics.FromPdfPage(page);
                }
                else
                {
                    // draw logo
                    Image LogoFileName = Image.FromFile(pdfObj.PdfFileDirectory + pdfObj.LogoFileName); //I store the logo locally
                    gfx.DrawImage(LogoFileName, 130f, 35f); //logo image, margin-left, margin-top

                    // draw Table with passed-in data
                    gfx.DrawImage(pdfObj.PageTwo, 0f, 100f); //the main content. The margin-top is set to 100f so it sits below the logo.
                }
            }

            using (MemoryStream stream = new MemoryStream())
            {
                document.Save(stream, true); //save via stream so I do not have to save this file locally and can then dispose of it, thus freeing things up
                pdfObj.PdfBytes = stream.ToArray(); //save the byte array of the stream to the object's byte[] property. Mandrill attachments need to be byte arrays and THIS is what we will be attaching
            }

            return document;
        }

        /// <summary>
        /// The Fax Cover Page is two pages - this is the first one. It displays the From, To, and disclaimer
        /// </summary>
        /// <param name="addressedTo">The name of the person this is being sent to.</param>
        /// <returns></returns>
        public static string CoverPage_Front(string addressedTo)
        {
            // Obviously altered.. You may format your fax cover sheet however you like
            return @"<html>
                        <body>
                            <div>
                                To: " + addressedTo + @", Cappuccino catcher luxurious admiral charity donate, luxurious big daft brush mouth coiffure clive dunn dickie davies charity donate admiral give him what-for john cleese. By jingo. big daft brush joseph stalin charming villain.
                            </div>
                        </body>
                    </html>";
        }

        /// <summary>
        /// The Fax Cover Page is two pages - this is the second one. It displays the logo and the table of data
        /// </summary>
        /// <param name="addressedTo"></param>
        /// <param name="dataFormattedIntoTable"></param>
        /// <returns></returns>
        public static string CoverPage_Content(string addressedTo, string dataFormattedIntoTable)
        {
            // Obviously altered..
            return @"<html>
                        <body>
                            <div>
                                <table border='0' cellpadding='0' style='background: #E8EBEB;'>
                                    <tbody>
                                        <tr>
                                            <td style='padding: .75pt .75pt .75pt .75pt'>
                                                <table border='0' cellpadding='0' style='background: white;'>
                                                    <tbody>
                                                        <tr>
                                                            <td style='border: none; border-bottom: solid #004A8F 4.5pt; padding: 0in 7.5pt 0in 7.5pt'>
                                                                To: " + addressedTo + @", Facial accessory doctor watson. wario arcu, yeoman farmer wario blue oyster bar charlie chaplin old man in pub hungarian nefarious cesar romero facial accessory doctor watson. arcu glorious facial hair? Frontiersman en time-warped cabbie great dictator um yesbaby toothbrush clone zone shopper. 

                                                                " + dataFormattedIntoTable + @"
                                                            </td>
                                                        </tr>
                                                    </tbody>
                                                </table>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </body>
                    </html>";
        }
    }


我真的希望这对您有帮助!! 这花了我一些时间弄清楚,现在效果很好。 请让我知道是否对此有任何改进,我将更新我的代码(和这篇文章)!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM