How to Convert Webpage to PDF Using .NET and Review in JavaScript
It's 3 am, and you just finished coding the last pieces of the new home page for your organization. You have spent countless hours getting this done and now need to ensure accuracy and compliance with your organization's marketing and sales policies and build out the SEO strategy for this new page. You have a large team that needs to review your work, but you don't want to slow things down by sending individual copies to each team member, then find a way to bring together all the changes without missing anything.
This is always a challenging stage for any project, but with GrapeCity's tools, this process is much easier. In this blog, we'll show you how to simplify this process and centralize the notes and changes related to the work done, all with just a few steps.
To summarize those steps, view your new page in a browser, convert the new page to a PDF file, and open the PDF file in GcPdfViewer for editing and collaboration with all the users. The last step is to open this document, then code your team's suggested/agreed-upon changes.
Ready to Try it Out? Download GrapeCity Documents for PDF Today!
Full Demonstrations
This process has three steps, all of which are completed with a few GrapeCity tools. This blog discusses specific pieces of these processes but doesn't have full code sets. The full code sets can be found in the following locations:
- For the first step - Converting a web page to a PDF using a URL
- The next step is to set up the GcPdfViewer for editing
- Lastly, set up the GcPdfViewer for sharing and collaboration
Once these steps have been completed, you now have an end-to-end solution for quick review and update of HTML pages, which includes comments, notes, edits, markup, and, if required, signatures and sign-offs of the work.
Let's take a closer look at this using an example.
First, the complete example (without the NuGet Packages) can be downloaded here.
After starting up Visual Studio 2022, follow these steps to get started:
Create a new project
Click on Create a new project, then select "Asp.NET Core Web App (Model-View-Controller)
Click "Next"
Name the application "HTML2PDF", and adjust the location if necessary.
Click "Next"
Then select ".NET 6.0 (Long-term support)" as your target framework:
Click "Create", then run the application to ensure the setup occurred correctly and the templated application runs as expected.
If you see this screen, congratulations; your application is ready for modifications!
Modify the Index.cshtml file to include the following code:
@{
ViewData["Title"] = "Home Page";
}
<style type="text/css">
.auto-style1 {
width: 100%;
}
.auto-style2 {
width: 192px;
}
.auto-style3 {
width: 80%;
border-style: solid;
border-width: 3px;
}
.auto-style4 {
width: 227px;
}
.auto-style6 {
width: 137px;
}
.auto-style7 {
width: 106px;
}
.auto-style8 {
background-color: darkturquoise;
}
.hide_print {
display: none;
}
</style>
<img src="treadstone-Logo.jpg" />
<a class="btn btn-primary" href=@Url.Action("DownloadTheFile")>Create PDF</a>
<h1>Healthcare - Intake Form</h1>
<p>
Please fill out all of the following fields in order for the Physicians to help you with your healthcare.
</p>
<p>
<strong>Demographic Information</strong>
</p>
<table border="0" class="auto-style1">
<tr>
<td class="auto-style2">First Name:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox1" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Last Name:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox2" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Address:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox3" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">City:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox4" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">State:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox5" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Zip Code:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox6" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Email:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox7" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Cell Phone:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox8" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">Next of Kin (NOK):</td>
<td>
<textarea rows="1" cols="30" ID="TextBox9" Width="520px"></textarea>
</td>
</tr>
<tr>
<td class="auto-style2">NOK Phone:</td>
<td>
<textarea rows="1" cols="30" ID="TextBox10" Width="520px"></textarea>
</td>
</tr>
</table>
<div id="canceryn">
<strong>
Medical History<br />
</strong> <table class="auto-style3">
<tr class="auto-style8">
<td class="auto-style4"><strong>Condition</strong></td>
<td class="auto-style7"><strong>Y/N</strong></td>
<td class="auto-style6"><strong>Date</strong></td>
</tr>
<tr>
<td class="auto-style4">Cancer</td>
<td class="auto-style7">
<input type="radio" ID="RdoCancer" value="Yes" name="cancer" />
<input type="radio" ID="RdoCancer" value="No" name="cancer" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox11"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Heart Disease</td>
<td class="auto-style7">
<input type="radio" ID="RadioHeart1" name="Heart" Text="Yes" />
<input type="radio" ID="RadioHeart2" name="Heart" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox12"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Kidney Disease</td>
<td class="auto-style7">
<input type="radio" ID="RadioKidney1" name="Kidney" Text="Yes" />
<input type="radio" ID="RadioKidney2" name="Kidney" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox13"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Smoking</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton7" name="Smoking" Text="Yes" />
<input type="radio" ID="RadioButton8" name="Smoking" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox14"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">High Blood Pressure</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton9" name="HBP" Text="Yes" />
<input type="radio" ID="RadioButton10" name="HBP" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox15"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">High Cholesterol </td>
<td class="auto-style7">
<input type="radio" ID="RadioButton11" name="HCL" Text="Yes" />
<input type="radio" ID="RadioButton12" name="HCL" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox16"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Broken Bones</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton13" name="Bones" Text="Yes" />
<input type="radio" ID="RadioButton14" name="Bones" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox17"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Back Pain</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton15" name="BackPain" Text="Yes" />
<input type="radio" ID="RadioButton16" name="BackPain" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox18"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Arthritis</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton17" name="Arthritis" Text="Yes" />
<input type="radio" ID="RadioButton18" name="Arthritis" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox19"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Diabetes</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton19" name="Diabetes" Text="Yes" />
<input type="radio" ID="RadioButton20" name="Diabetes" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox20"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Eye Disorder</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton21" name="Eye" Text="Yes" />
<input type="radio" ID="RadioButton22" name="Eye" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox21"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Neurological Disorder</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton23" name="Neuro" Text="Yes" />
<input type="radio" ID="RadioButton24" name="Neuro" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox22"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Psychiatric Disorder</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton25" name="Psych" Text="Yes" />
<input type="radio" ID="RadioButton26" name="Psych" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox23"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Pulmonary Embolism</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton27" name="PE" Text="Yes" />
<input type="radio" ID="RadioButton28" name="PE" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox24"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Stroke</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton29" name="Stroke" Text="Yes" />
<input type="radio" ID="RadioButton30" name="Stroke" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox25"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Seizure or Epilepsy</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton31" name="Seizure" Text="Yes" />
<input type="radio" ID="RadioButton32" name="Seizure" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox26"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Thyroid Disorder</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton33" name="Thyroid" Text="Yes" />
<input type="radio" ID="RadioButton34" name="Thyroid" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox27"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Asthma/Breathing Issues</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton35" name="Asthma" Text="Yes" />
<input type="radio" ID="RadioButton36" name="Asthma" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox28"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Bleeding/Clotting Disorder</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton37" name="Bleeding" Text="Yes" />
<input type="radio" ID="RadioButton38" name="Bleeding" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox29"></textarea>
</td>
</tr>
<tr>
<td class="auto-style4">Bowel/Stomach Problems</td>
<td class="auto-style7">
<input type="radio" ID="RadioButton39" name="Bowel" Text="Yes" />
<input type="radio" ID="RadioButton40" name="Bowel" Text="No" />
</td>
<td class="auto-style6">
<textarea rows="1" cols="30" ID="TextBox30"></textarea>
<textarea rows="1" cols="30" ID="TextBox31"></textarea>
</td>
</tr>
</table>
</div>
Rerun the application to make sure the changes have taken effect. The new page should look like this:
Close the application and open up the "HomeController.cs" file.
Right-click on "Dependencies" and select "Manage NuGet Packages". Browse for "Grapecity.Documents.Html" and install the NuGet Package:
Add the following using statements to the top of the "HomeController.cs" file (if not already there):
using HTML2PDF.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using GrapeCity.Documents.Html;
using System.Drawing;
Add the following code within the "Homecontroller.cs" file within the namespace brackets:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
public ActionResult DownloadTheFile()
{
var myUri = Request.GetTypedHeaders().Referer;
var tmp = Path.GetTempFileName();
var path = new BrowserFetcher().GetDownloadedPath();
using (var re = new GcHtmlBrowser(path))
//load the HTML
using (var pg = re.NewPage(myUri, new PageOptions
{
WindowSize = new System.Drawing.Size(1024,768),
DefaultBackgroundColor = Color.LavenderBlush
}))
{
//save HTML as PDF file
pg.SaveAsPdf(tmp, new PdfOptions
{
FullPage = true
});
var ts = new TempStream(tmp);
return File(ts, "application/pdf", "SampleHTML2PDF.pdf"); // todo: update the PDF name
}
}
/// <summary>
/// Utility class to ensure that temp files are deleted.
/// </summary>
private class TempStream : FileStream {
static object s_lock = new object();
private string _path;
public TempStream(string path) : base(path, FileMode.Open, FileAccess.Read, FileShare.None)
{
_path = path;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
lock (s_lock)
{
if (System.IO.File.Exists(_path))
System.IO.File.Delete(_path);
}
}
}
}
Run your application, and you should see a screen similar to the following:
Click the "Create PDF" button, and a new file download should start (there could be a slight delay, so be patient) - the file will be downloaded to your local drive based on the settings within the specific browser you are using.
Open the downloaded file, and you should have a PDF that looks remarkably similar to the web page and can now be used for the team to do markup utilizing GrapeCity's PDF reader.
To open in Grapecity's PDF Reader and test, you can either stand up your own local GcPdfViewer instance or load the downloaded file into our demonstration GcPdfViewer site here.
Opening in the GcPdfViewer, the saved document will look like this, and the ability to comment, annotate and modify will be available (depending on GcPdfViewer Settings and privileges):
Don't hesitate to contact us with any questions, and happy coding!
Download this full example here.
GrapeCity’s .NET PDF API Library and JavaScript PDF Viewer
This article only scratches the surface of the full capabilities of the GrapeCity Documents for PDF (GcPdf) and the client-side JS PDF Viewer (GcPdfViewer). Review our documentation to see the many available features, and check out our GcPdf and GcPdfViewer demos to see the features in action with downloadable sample projects. Integrating this .NET PDF server-side API into a desktop or web-based application allows developers to programmatically import/export, create AcroForms (PDF Forms), and deploy PDFs across desktop and web applications at scale. The JavaScript PDF viewer allows users to read and edit PDFs on the web, and open and print across browsers and frameworks. To learn more about GcPdf and GcPdfViewer’s latest features, check out our release blog.
Ready to Try it Out? Download GrapeCity Documents for PDF Today!