SelectPdf Free Edition supports up to 5 pages per document. That’s why we generate two parts and merge.
Install these
dotnet add package Select.Pdf.NetCore
dotnet add package PdfSharp
Full Working Code
using System;
using System.IO;
using System.Net;
using System.Text;
using SelectPdf;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
class HtmlAgreementPdfGenerator
{
static void Main()
{
string base64Merged = GenerateMergedPdfFromAgreement();
File.WriteAllBytes("FinalAgreement.pdf", Convert.FromBase64String(base64Merged));
Console.WriteLine("✅ Merged PDF saved as 'FinalAgreement.pdf'");
}
public static string GenerateMergedPdfFromAgreement()
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Generate first 5 pages (allowed by SelectPdf free version)
StringBuilder htmlFirst5Pages = new StringBuilder();
for (int i = 1; i <= 5; i++)
{
htmlFirst5Pages.Append(BuildAgreementHtml(i));
}
// Generate remaining 2 pages
StringBuilder htmlLast2Pages = new StringBuilder();
for (int i = 6; i <= 7; i++)
{
htmlLast2Pages.Append(BuildAgreementHtml(i));
}
// Convert both HTML segments to Base64 PDF
string base64Pdf1to5 = ConvertHtmlToBase64Pdf(htmlFirst5Pages.ToString());
string base64Pdf6to7 = ConvertHtmlToBase64Pdf(htmlLast2Pages.ToString());
// Merge both into one Base64 PDF
return MergeBase64Pdfs(base64Pdf1to5, base64Pdf6to7);
}
private static string BuildAgreementHtml(int pageNumber)
{
StringBuilder sb = new StringBuilder();
sb.Append("<html><head><style>");
sb.Append("body { font-family: Arial; line-height: 1.6; margin: 40px; }");
sb.Append("h1, h2 { color: #333; }");
sb.Append("p { text-align: justify; }");
sb.Append("</style></head><body>");
sb.Append($"<h1>Service Agreement - Page {pageNumber}</h1>");
sb.Append("<h2>1. Introduction</h2>");
sb.Append("<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam.</p>");
sb.Append("<h2>2. Terms and Conditions</h2>");
for (int i = 0; i < 5; i++)
{
sb.Append("<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>");
}
sb.Append("<h2>3. Confidentiality</h2>");
for (int i = 0; i < 3; i++)
{
sb.Append("<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>");
}
sb.Append("<h2>4. Termination</h2>");
sb.Append("<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>");
sb.Append("<h2>5. Signatures</h2>");
sb.Append("<p>Signed by both parties as a binding agreement.</p>");
sb.Append("</body></html>");
return sb.ToString();
}
private static string ConvertHtmlToBase64Pdf(string html)
{
HtmlToPdf converter = new HtmlToPdf();
converter.Options.PdfPageSize = PdfPageSize.A4;
converter.Options.WebPageWidth = 1024;
converter.Options.MarginTop = 20;
converter.Options.MarginBottom = 20;
PdfDocument doc = converter.ConvertHtmlString(html);
using (MemoryStream ms = new MemoryStream())
{
doc.Save(ms);
doc.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
private static string MergeBase64Pdfs(string base64Pdf1, string base64Pdf2)
{
byte[] pdfBytes1 = Convert.FromBase64String(base64Pdf1);
byte[] pdfBytes2 = Convert.FromBase64String(base64Pdf2);
PdfDocument input1 = PdfReader.Open(new MemoryStream(pdfBytes1), PdfDocumentOpenMode.Import);
PdfDocument input2 = PdfReader.Open(new MemoryStream(pdfBytes2), PdfDocumentOpenMode.Import);
PdfDocument merged = new PdfDocument();
for (int i = 0; i < input1.PageCount; i++)
merged.AddPage(input1.Pages[i]);
for (int i = 0; i < input2.PageCount; i++)
merged.AddPage(input2.Pages[i]);
using (MemoryStream outputMs = new MemoryStream())
{
merged.Save(outputMs);
return Convert.ToBase64String(outputMs.ToArray());
}
}
}
No comments:
Post a Comment