コード例 #1
0
        /// <summary>
        /// Use a .NET PrintPreview Dialog to print (or not print) this (possibly multi-page) HTML document.
        /// </summary>
        /// <param name="HtmlPages"></param>
        public static void PreviewOrPrint(String HtmlPages)
        {
            System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
            bool printerInstalled = printDocument.PrinterSettings.IsValid;

            if (!printerInstalled)
            {
                MessageBox.Show(Catalog.GetString("There is no printer, so printing is not possible"));
                return;
            }

            TGfxPrinter  GfxPrinter  = new TGfxPrinter(printDocument, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            TPrinterHtml htmlPrinter = new TPrinterHtml(HtmlPages,
                                                        TAppSettingsManager.GetValue("Formletters.Path"),
                                                        GfxPrinter);

            GfxPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

            CoolPrintPreviewDialog PrintDlg = new CoolPrintPreviewDialog();

            PrintDlg.Document   = GfxPrinter.Document;
            PrintDlg.ClientSize = new System.Drawing.Size(500, 720);
            try
            {
                PrintDlg.ShowDialog();
            }
            catch (Exception)  // if the user presses Cancel, an exception may be raised!
            {
            }
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="AllLetters">HTML text (could be several pages)</param>
        /// <param name="APathForImagesBase">Could be null if I'm not printing images!</param>
        public void PreviewOrPrint(String AllLetters, String APathForImagesBase)
        {
            System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
            bool printerInstalled = printDocument.PrinterSettings.IsValid;

            if (!printerInstalled)
            {
                MessageBox.Show(Catalog.GetString("There is no printer, so printing is not possible"));
                return;
            }

            FGfxPrinter = new TGfxPrinter(printDocument, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            try
            {
                TPrinterHtml htmlPrinter = new TPrinterHtml(AllLetters,
                                                            APathForImagesBase,
                                                            FGfxPrinter);
                FGfxPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);
                this.ppvLetters.InvalidatePreview();
                this.ppvLetters.Document       = FGfxPrinter.Document;
                this.ppvLetters.Zoom           = 1;
                FGfxPrinter.Document.EndPrint += new PrintEventHandler(this.EndPrint);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
コード例 #3
0
        public void TestPDFPrinter()
        {
            const string FileName = "../../csharp/ICT/Testing/lib/Common/Printing/test.html";
            string       TextToPrint;

            if (!File.Exists(FileName))
            {
                TextToPrint = "<html><body>" + String.Format("Cannot find file {0}", FileName) + "</body></html>";
            }
            else
            {
                StreamReader r = new StreamReader(FileName);
                TextToPrint = r.ReadToEnd();
                r.Close();
            }

            TPdfPrinter  pdfPrinter  = new TPdfPrinter(TPdfPrinter.ePrinterBehaviour.eFormLetter);
            TPrinterHtml htmlPrinter = new TPrinterHtml(TextToPrint,
                                                        String.Empty,
                                                        pdfPrinter);

            pdfPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

            pdfPrinter.SavePDF("test.pdf");
        }
コード例 #4
0
ファイル: MainForm.cs プロジェクト: lulzzz/openpetra
        void TbbSavePDFClick(object sender, EventArgs e)
        {
            PrintDocument doc = new PrintDocument();

            TPdfPrinter  pdfPrinter  = new TPdfPrinter(doc, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            TPrinterHtml htmlPrinter = new TPrinterHtml(txtHTMLText.Text,
                                                        String.Empty,
                                                        pdfPrinter);

            pdfPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

            pdfPrinter.SavePDF("test.pdf");

            System.Diagnostics.Process.Start(Path.GetFullPath("test.pdf"));
        }
コード例 #5
0
        /// <summary>
        /// Generate a PDF from an HTML Document, can contain several pages
        /// </summary>
        /// <returns>path of the temporary PDF file</returns>
        public static string GeneratePDFFromHTML(string AHTMLDoc, string APdfPath)
        {
            if (AHTMLDoc.Length == 0)
            {
                return(string.Empty);
            }

            if (!Directory.Exists(APdfPath))
            {
                Directory.CreateDirectory(APdfPath);
            }

            Random rand     = new Random();
            string filename = string.Empty;

            do
            {
                filename = APdfPath + Path.DirectorySeparatorChar +
                           rand.Next(1, 1000000).ToString() + ".pdf";
            } while (File.Exists(filename));

            if (TLogging.DebugLevel > 0)
            {
                StreamWriter sw = new StreamWriter(filename.Replace(".pdf", ".html"));
                sw.WriteLine(AHTMLDoc);
                sw.Close();
            }

            try
            {
                PrintDocument doc = new PrintDocument();

                TPdfPrinter  pdfPrinter  = new TPdfPrinter(doc, TGfxPrinter.ePrinterBehaviour.eFormLetter);
                TPrinterHtml htmlPrinter = new TPrinterHtml(AHTMLDoc, String.Empty, pdfPrinter);

                pdfPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

                pdfPrinter.SavePDF(filename);
            }
            catch (Exception e)
            {
                TLogging.Log("Exception while writing PDF: " + e.Message);
                TLogging.Log(e.StackTrace);
                throw;
            }

            return(filename);
        }
コード例 #6
0
ファイル: MainForm.cs プロジェクト: lulzzz/openpetra
        void TbbPreviewClick(object sender, EventArgs e)
        {
            PrintDocument doc = new PrintDocument();

            FGfxPrinter = new TGfxPrinter(doc, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            TPrinterHtml htmlPrinter = new TPrinterHtml(txtHTMLText.Text,
                                                        String.Empty,
                                                        FGfxPrinter);

            FGfxPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

            doc.EndPrint += new PrintEventHandler(this.PrintDocument_EndPrint);

            printPreviewControl1.Document = doc;
            printPreviewControl1.InvalidatePreview();

            printPreviewControl1.Rows = 1;
        }
コード例 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="APaymentNum"></param>
        /// <param name="ALedgerNumber"></param>
        public void PrintRemittanceAdvice(Int32 APaymentNum, Int32 ALedgerNumber)
        {
            FLedgerNumber = ALedgerNumber;

            txtPaymentNum.NumberValueInt = APaymentNum;
            AccountsPayableTDS PaymentDetails = TRemote.MFinance.AP.WebConnectors.LoadAPPayment(ALedgerNumber, APaymentNum);

            if (PaymentDetails.AApPayment.Rows.Count == 0) // unable to load this payment..
            {
                lblLoadStatus.Text = String.Format(Catalog.GetString("Error - can't load Payment number {0}."), APaymentNum);
                return;
            }

            SortedList <string, List <string> > FormValues = new SortedList <string, List <string> >();

            //
            // load my own country code, so I don't print it on letters to my own country.
            //
            string LocalCountryCode = TRemote.MPartner.Partner.ServerLookups.WebConnectors.GetCountryCodeFromSiteLedger();

            //
            // These are the fields that I will pull out of the TDS...
            //
            FormValues.Add("SupplierName", new List <string>());
            FormValues.Add("SupplierAddress", new List <string>());
            FormValues.Add("PaymentDate", new List <string>());
            FormValues.Add("OurReference", new List <string>());
            FormValues.Add("InvoiceDate", new List <string>());
            FormValues.Add("InvoiceNumber", new List <string>());
            FormValues.Add("InvoiceAmount", new List <string>());
            FormValues.Add("TotalPayment", new List <string>());

            FormValues["SupplierName"].Add(PaymentDetails.PPartner[0].PartnerShortName);

            if (PaymentDetails.PLocation[0].CountryCode == LocalCountryCode)
            {
                PaymentDetails.PLocation[0].CountryCode = ""; // Don't print country code it it's the same as my own.
            }

            FormValues["SupplierAddress"].Add(Calculations.DetermineLocationString(PaymentDetails.PLocation[0],
                                                                                   Calculations.TPartnerLocationFormatEnum.plfHtmlLineBreak));

            String DatePattern = Thread.CurrentThread.CurrentCulture.DateTimeFormat.LongDatePattern;

            DatePattern = "dd MMMM yyyy"; // The long pattern above is no good in UK, although it might be OK in other cultures...

            FormValues["PaymentDate"].Add(PaymentDetails.AApPayment[0].PaymentDate.Value.ToString(DatePattern));
            FormValues["OurReference"].Add(PaymentDetails.AApSupplier[0].OurReference);

            foreach (AApDocumentRow Row in PaymentDetails.AApDocument.Rows)
            {
                FormValues["InvoiceDate"].Add(Row.DateIssued.ToString(DatePattern));
                FormValues["InvoiceNumber"].Add(Row.DocumentCode);
                FormValues["InvoiceAmount"].Add(Row.TotalAmount.ToString("n2") + " " + PaymentDetails.AApSupplier[0].CurrencyCode);
            }

            FormValues["TotalPayment"].Add(PaymentDetails.AApPayment[0].Amount.ToString("n2") + " " + PaymentDetails.AApSupplier[0].CurrencyCode);

            String TemplateFilename = TAppSettingsManager.GetValue("Formletters.Path") + "\\ApRemittanceAdvice.html";

            if (!File.Exists(TemplateFilename))
            {
                lblLoadStatus.Text = String.Format(Catalog.GetString("Error - unable to load HTML template from {0}"), TemplateFilename);
                return;
            }

            FHtmlDoc = TFormLettersTools.PrintSimpleHTMLLetter(TemplateFilename, FormValues);

            System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
            bool printerInstalled = printDocument.PrinterSettings.IsValid;

            if (!printerInstalled)
            {
                lblLoadStatus.Text = Catalog.GetString("There is no printer, so printing is not possible");
                return;
            }

            FGfxPrinter = new TGfxPrinter(printDocument, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            try
            {
                TPrinterHtml htmlPrinter = new TPrinterHtml(FHtmlDoc,
                                                            TAppSettingsManager.GetValue("Formletters.Path"),
                                                            FGfxPrinter);
                FGfxPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);
                this.ppvLetters.InvalidatePreview();
                this.ppvLetters.Document = FGfxPrinter.Document;
                this.ppvLetters.Zoom     = 1;
                // GfxPrinter.Document.EndPrint += new PrintEventHandler(this.EndPrint);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            btnPDF.Visible  = true;
            btnCopy.Visible = true;

            lblLoadStatus.Text = "";
        }
コード例 #8
0
        /// <summary>
        /// Format the letter for the donor with all the gifts
        ///
        /// Can also used for a single receipt.
        /// </summary>
        /// <returns>One or more html documents, each in its own body tag, for printing with the HTML printer</returns>
        private static string FormatLetter(Int64 ADonorKey,
                                           string ADonorName,
                                           DataTable ADonations,
                                           string ABaseCurrency,
                                           string AHTMLTemplate,
                                           string ALedgerCountryCode,
                                           TDBTransaction ATransaction)
        {
            // get details of the donor, and best address

            PLocationTable        Location;
            PPartnerLocationTable PartnerLocation;
            string CountryName;
            string EmailAddress;

            if (!TAddressTools.GetBestAddress(ADonorKey, out Location, out PartnerLocation, out CountryName, out EmailAddress, ATransaction))
            {
                return("");
            }

            bool TaxDeductiblePercentageEnabled = Convert.ToBoolean(
                TSystemDefaults.GetSystemDefault(SharedConstants.SYSDEFAULT_TAXDEDUCTIBLEPERCENTAGE, "FALSE"));

            string msg = AHTMLTemplate;

            if (ADonorName.Contains(","))
            {
                msg = msg.Replace("#TITLE", Calculations.FormatShortName(ADonorName, eShortNameFormat.eOnlyTitle));
            }
            else
            {
                // organisations have no title
                msg = msg.Replace("#TITLE", "");
            }

            msg = msg.Replace("#NAME", Calculations.FormatShortName(ADonorName, eShortNameFormat.eReverseWithoutTitle));
            msg = msg.Replace("#STREETNAME", GetStringOrEmpty(Location[0].StreetName));
            msg = msg.Replace("#LOCATION", GetStringOrEmpty(Location[0].Locality));
            msg = msg.Replace("#ADDRESS3", GetStringOrEmpty(Location[0].Address3));
            msg = msg.Replace("#BUILDING1", GetStringOrEmpty(Location[0].Building1));
            msg = msg.Replace("#BUILDING2", GetStringOrEmpty(Location[0].Building2));
            msg = msg.Replace("#CITY", GetStringOrEmpty(Location[0].City));
            msg = msg.Replace("#POSTALCODE", GetStringOrEmpty(Location[0].PostalCode));
            msg = msg.Replace("#DATE", DateTime.Now.ToString("d. MMMM yyyy"));

            // according to German Post, there is no country code in front of the post code
            // if country code is same for the address of the recipient and this office, then COUNTRYNAME is cleared
            if (GetStringOrEmpty(Location[0].CountryCode) != ALedgerCountryCode)
            {
                msg = msg.Replace("#COUNTRYNAME", CountryName);
            }
            else
            {
                msg = msg.Replace("#COUNTRYNAME", "");
            }

            // recognise detail lines automatically
            string RowTemplate;

            msg = TPrinterHtml.GetTableRow(msg, "#AMOUNT", out RowTemplate);
            string  OrigRowTemplate = RowTemplate;
            string  rowTexts        = "";
            decimal sum             = 0;
            decimal sumTaxDeduct    = 0;
            decimal sumNonDeduct    = 0;

            decimal  prevAmount          = 0.0M;
            decimal  prevAmountTaxDeduct = 0.0M;
            decimal  prevAmountNonDeduct = 0.0M;
            string   prevCurrency        = String.Empty;
            string   prevCommentOne      = String.Empty;
            string   prevAccountDesc     = String.Empty;
            string   prevCostCentreDesc  = String.Empty;
            string   prevgifttype        = string.Empty;
            DateTime prevDateEntered     = DateTime.MaxValue;

            foreach (DataRow rowGifts in ADonations.Rows)
            {
                DateTime dateEntered         = Convert.ToDateTime(rowGifts["DateEntered"]);
                decimal  amount              = Convert.ToDecimal(rowGifts["TransactionAmount"]);
                decimal  taxDeductibleAmount = 0;
                decimal  nonDeductibleAmount = 0;
                string   currency            = rowGifts["Currency"].ToString();
                string   commentOne          = rowGifts["CommentOne"].ToString();
                string   accountDesc         = rowGifts["AccountDesc"].ToString();
                string   costcentreDesc      = rowGifts["CostCentreDesc"].ToString();
                string   gifttype            = rowGifts["GiftType"].ToString();
                RowTemplate = OrigRowTemplate;

                sum += Convert.ToDecimal(rowGifts["AmountInBaseCurrency"]);

                if (TaxDeductiblePercentageEnabled)
                {
                    taxDeductibleAmount = Convert.ToDecimal(rowGifts["TaxDeductibleAmount"]);
                    nonDeductibleAmount = Convert.ToDecimal(rowGifts["NonDeductibleAmount"]);
                    sumTaxDeduct       += Convert.ToDecimal(rowGifts["TaxDeductibleAmountBase"]);
                    sumNonDeduct       += Convert.ToDecimal(rowGifts["NonDeductibleAmountBase"]);
                }

                // can we sum up donations on the same date, or do we need to print each detail with the account description?
                if (RowTemplate.Contains("#COMMENTONE") || RowTemplate.Contains("#ACCOUNTDESC") || RowTemplate.Contains("#COSTCENTREDESC"))
                {
                    if (gifttype == MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND)
                    {
                        RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT);
                    }
                    else if (gifttype == MFinanceConstants.GIFT_TYPE_GIFT)
                    {
                        RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND);
                    }

                    rowTexts += RowTemplate.
                                Replace("#DONATIONDATE", dateEntered.ToString("dd.MM.yyyy")).
                                Replace("#AMOUNTCURRENCY", currency).
                                Replace("#AMOUNT", StringHelper.FormatUsingCurrencyCode(amount, currency)).
                                Replace("#TAXDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(taxDeductibleAmount, currency)).
                                Replace("#TAXNONDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(nonDeductibleAmount, currency)).
                                Replace("#COMMENTONE", commentOne).
                                Replace("#ACCOUNTDESC", accountDesc).
                                Replace("#COSTCENTREDESC", costcentreDesc);
                }
                else
                {
                    if ((dateEntered != prevDateEntered) && (prevDateEntered != DateTime.MaxValue))
                    {
                        if (prevgifttype == MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND)
                        {
                            RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT);
                        }
                        else if (prevgifttype == MFinanceConstants.GIFT_TYPE_GIFT)
                        {
                            RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND);
                        }

                        rowTexts += RowTemplate.
                                    Replace("#DONATIONDATE", prevDateEntered.ToString("dd.MM.yyyy")).
                                    Replace("#AMOUNTCURRENCY", prevCurrency).
                                    Replace("#AMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmount, prevCurrency)).
                                    Replace("#TAXDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmountTaxDeduct, prevCurrency)).
                                    Replace("#TAXNONDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmountNonDeduct, prevCurrency)).
                                    Replace("#COMMENTONE", prevCommentOne).
                                    Replace("#ACCOUNTDESC", prevAccountDesc).
                                    Replace("#COSTCENTREDESC", prevCostCentreDesc);
                        prevAmount = amount;

                        if (TaxDeductiblePercentageEnabled)
                        {
                            prevAmountTaxDeduct = taxDeductibleAmount;
                            prevAmountNonDeduct = nonDeductibleAmount;
                        }
                    }
                    else
                    {
                        prevAmount += amount;

                        if (TaxDeductiblePercentageEnabled)
                        {
                            prevAmountTaxDeduct += taxDeductibleAmount;
                            prevAmountNonDeduct += nonDeductibleAmount;
                        }
                    }

                    prevCurrency       = currency;
                    prevDateEntered    = dateEntered;
                    prevCommentOne     = commentOne;
                    prevAccountDesc    = accountDesc;
                    prevCostCentreDesc = costcentreDesc;
                    prevgifttype       = gifttype;
                }
            }

            if (prevDateEntered != DateTime.MaxValue)
            {
                RowTemplate = OrigRowTemplate;

                if (prevgifttype == MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND)
                {
                    RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT);
                }
                else if (prevgifttype == MFinanceConstants.GIFT_TYPE_GIFT)
                {
                    RowTemplate = TPrinterHtml.RemoveDivWithClass(RowTemplate, MFinanceConstants.GIFT_TYPE_GIFT_IN_KIND);
                }

                rowTexts += RowTemplate.
                            Replace("#DONATIONDATE", prevDateEntered.ToString("dd.MM.yyyy")).
                            Replace("#AMOUNTCURRENCY", prevCurrency).
                            Replace("#AMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmount, prevCurrency)).
                            Replace("#TAXDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmountTaxDeduct, prevCurrency)).
                            Replace("#TAXNONDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(prevAmountNonDeduct, prevCurrency)).
                            Replace("#COMMENTONE", prevCommentOne).
                            Replace("#ACCOUNTDESC", prevAccountDesc).
                            Replace("#COSTCENTREDESC", prevCostCentreDesc);
                prevAmount = 0.0M;

                if (TaxDeductiblePercentageEnabled)
                {
                    prevAmountTaxDeduct = 0.0M;
                    prevAmountNonDeduct = 0.0M;
                }
            }

            msg = msg.Replace("#OVERALLAMOUNTCURRENCY", ABaseCurrency).
                  Replace("#OVERALLAMOUNT", StringHelper.FormatUsingCurrencyCode(sum, ABaseCurrency)).
                  Replace("#OVERALLTAXDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(sumTaxDeduct, ABaseCurrency)).
                  Replace("#OVERALLTAXNONDEDUCTAMOUNT", StringHelper.FormatUsingCurrencyCode(sumNonDeduct, ABaseCurrency));

            if ((ADonations.Rows.Count == 1) && msg.Contains("#DONATIONDATE"))
            {
                // this is a receipt for just one gift
                msg = msg.Replace("#DONATIONDATE", Convert.ToDateTime(ADonations.Rows[0]["DateEntered"]).ToString("dd.MM.yyyy"));
            }

            // TODO allow other currencies. use a_currency table, and base currency
            msg = msg.Replace("#TOTALAMOUNTINWORDS", NumberToWords.AmountToWords(sum, "Euro", "Cent")).
                  Replace("#TOTALTAXDEDUCTAMOUNTINWORDS", NumberToWords.AmountToWords(sumTaxDeduct, "Euro", "Cent")).
                  Replace("#TOTALTAXNONDEDUCTAMOUNTINWORDS", NumberToWords.AmountToWords(sumNonDeduct, "Euro", "Cent"));

            return(msg.Replace("#ROWTEMPLATE", rowTexts));
        }
コード例 #9
0
        /// create PDF
        public static string GeneratePDF(Int64 APartnerKey, string ACountryCode, TApplicationFormData AData, out string ADownloadIdentifier)
        {
            string FileName = TFormLettersTools.GetRoleSpecificFile(TAppSettingsManager.GetValue("Formletters.Path"),
                                                                    "ApplicationPDF",
                                                                    AData.registrationcountrycode,
                                                                    AData.formsid,
                                                                    "html");

            string HTMLText = string.Empty;

            if (!File.Exists(FileName))
            {
                HTMLText = "<html><body>" + String.Format("Cannot find file {0}", FileName) + "</body></html>";
            }
            else
            {
                StreamReader r = new StreamReader(FileName);
                HTMLText = r.ReadToEnd();
                r.Close();
            }

            if ((AData.existingpartnerkey != null) && AData.existingpartnerkey.StartsWith("If you cannot find it"))
            {
                AData.RawData            = AData.RawData.Replace(AData.existingpartnerkey, "N/A");
                AData.existingpartnerkey = "";
            }

            if (AData.groupwish == null)
            {
                Regex regex = new Regex(@"^.*#GROUPWISH.*$", RegexOptions.Multiline);
                HTMLText = regex.Replace(HTMLText, "");
            }

            HTMLText = TJsonTools.ReplaceKeywordsWithData(AData.RawData, HTMLText);

            HTMLText = HTMLText.Replace("#DATE", StringHelper.DateToLocalizedString(DateTime.Today));
            HTMLText = HTMLText.Replace("#FORMLETTERPATH", TAppSettingsManager.GetValue("Formletters.Path"));
            HTMLText = HTMLText.Replace("#REGISTRATIONID", StringHelper.FormatStrToPartnerKeyString(APartnerKey.ToString()));
            HTMLText = HTMLText.Replace("#PHOTOPARTICIPANT", TAppSettingsManager.GetValue("Server.PathData") +
                                        Path.DirectorySeparatorChar + "photos" +
                                        Path.DirectorySeparatorChar + APartnerKey.ToString() + ".jpg");

            HTMLText = HTMLText.Replace("#HTMLRAWDATA", TJsonTools.DataToHTMLTable(AData.RawData));

            PrintDocument doc = new PrintDocument();

            TPdfPrinter  pdfPrinter  = new TPdfPrinter(doc, TGfxPrinter.ePrinterBehaviour.eFormLetter);
            TPrinterHtml htmlPrinter = new TPrinterHtml(HTMLText,
                                                        String.Empty,
                                                        pdfPrinter);

            pdfPrinter.Init(eOrientation.ePortrait, htmlPrinter, eMarginType.ePrintableArea);

            string pdfPath = TAppSettingsManager.GetValue("Server.PathData") + Path.DirectorySeparatorChar +
                             "pdfs";

            if (!Directory.Exists(pdfPath))
            {
                Directory.CreateDirectory(pdfPath);
            }

            string pdfFilename = pdfPath + Path.DirectorySeparatorChar + APartnerKey.ToString() + ".pdf";

            pdfPrinter.SavePDF(pdfFilename);

            string downloadPath = TAppSettingsManager.GetValue("Server.PathData") + Path.DirectorySeparatorChar +
                                  "downloads";

            if (!Directory.Exists(downloadPath))
            {
                Directory.CreateDirectory(downloadPath);
            }

            // Create a link file for this PDF
            ADownloadIdentifier = TPatchTools.GetMd5Sum(pdfFilename);
            StreamWriter sw = new StreamWriter(downloadPath + Path.DirectorySeparatorChar + ADownloadIdentifier + ".txt");

            sw.WriteLine("pdfs");
            sw.WriteLine(Path.GetFileName(pdfFilename));
            sw.Close();

            return(pdfFilename);
        }