Contents
1. Introduction
If you want to handle the PDF in .Net project, I think you would know the iTextSharp
, it really a powerful PDF handler library, however, it not allow to free to use in commercial after version 2.1.7, and Free Spire.PDF is a Community Edition of the Spire.PDF for .NET, which is a totally free PDF API for commercial and personal use. As a standalone .NET library, Free Spire.PDF for .NET enables developers to create, write, edit, convert, print, handle and read PDF files on any .NET( C#, VB.NET, ASP.NET, .NET Core) applications.
I will base on the previous MyDemo
project to demonstrate how to do it.
2. Create the API
2.1 Install Free Spire.PDF from Nuget
First, we need to install the Free Spire.PDF into API project from Nuget
2.2 Create the Controller
Create the GeneratePDFController
and action Generate
and then create the PDF demo page below
1) Create the pdfDocument
and page
//Create a PdfDocument object
PdfDocument doc = new PdfDocument();
//Add a page
PdfPageBase page = doc.Pages.Add();
the elements will be put in the page base on x
and y
coordinates, so we can define the started coordinates
//Initialize x and y coordinates
float baseX = 100;
float baseY = 30;
create two brush for different font color and create a font
PdfSolidBrush brush1 = new PdfSolidBrush(new PdfRGBColor(Color.Blue));
PdfSolidBrush brush2 = new PdfSolidBrush(new PdfRGBColor(Color.Black));
PdfFont font = new PdfFont(PdfFontFamily.TimesRoman, 12f, PdfFontStyle.Regular);
We want to put a label on left, it can use page.Canvas.DrawString
to draw a label, it’s base on the font
and brush
, and use the PointF
to control the position
page.Canvas.DrawString("TextBox:", font, brush1, new PointF(10, baseY));
and draw the TextBox element neat the label on the right, define the position with RectangleF
, create the textbox with PdfTextBoxField
RectangleF tbxBounds = new RectangleF(baseX, baseY, 150, 15);
PdfTextBoxField textBox = new PdfTextBoxField(page, "textbox");
textBox.Bounds = tbxBounds;
textBox.Text = "Hello World!";
textBox.Font = font;
in the end, don’t forget add the text box element into PdfDocument
, because this is a form element, so use below, and also need to update the y
coordinate
doc.Form.Fields.Add(textBox);
baseY += 25;
and then, create two checkboxes in second row
//label
page.Canvas.DrawString("CheckBox:", font, brush1, new PointF(10, baseY));
RectangleF checkboxBound1 = new RectangleF(baseX, baseY, 15, 15);
PdfCheckBoxField checkBoxField1 = new PdfCheckBoxField(page, "checkbox1");
checkBoxField1.Bounds = checkboxBound1;
checkBoxField1.Checked = false;
//checkbox value description
page.Canvas.DrawString("Option 1", font, brush2, new PointF(baseX + 20, baseY));
RectangleF checkboxBound2 = new RectangleF(baseX + 70, baseY, 15, 15);
PdfCheckBoxField checkBoxField2 = new PdfCheckBoxField(page, "checkbox2");
checkBoxField2.Bounds = checkboxBound2;
checkBoxField2.Checked = false;
page.Canvas.DrawString("Option 2", font, brush2, new PointF(baseX + 90, baseY));
//add to the doc form
doc.Form.Fields.Add(checkBoxField1);
doc.Form.Fields.Add(checkBoxField2);
//update y coordinate
baseY += 25;
create the radio buttons
page.Canvas.DrawString("RadioButton:", font, brush1, new PointF(10, baseY));
PdfRadioButtonListField radioButtonListField = new PdfRadioButtonListField(page, "radio");
PdfRadioButtonListItem radioItem1 = new PdfRadioButtonListItem("option1");
RectangleF radioBound1 = new RectangleF(baseX, baseY, 15, 15);
radioItem1.Bounds = radioBound1;
page.Canvas.DrawString("Option 1", font, brush2, new PointF(baseX + 20, baseY));
PdfRadioButtonListItem radioItem2 = new PdfRadioButtonListItem("option2");
RectangleF radioBound2 = new RectangleF(baseX + 70, baseY, 15, 15);
radioItem2.Bounds = radioBound2;
page.Canvas.DrawString("Option 2", font, brush2, new PointF(baseX + 90, baseY));
radioButtonListField.Items.Add(radioItem1);
radioButtonListField.Items.Add(radioItem2);
radioButtonListField.SelectedIndex = 0;
doc.Form.Fields.Add(radioButtonListField);
baseY += 25;
create a combobox
page.Canvas.DrawString("ComboBox:", font, brush1, new PointF(10, baseY));
RectangleF cmbBounds = new RectangleF(baseX, baseY, 150, 15);
PdfComboBoxField comboBoxField = new PdfComboBoxField(page, "combobox");
comboBoxField.Bounds = cmbBounds;
comboBoxField.Items.Add(new PdfListFieldItem("Item 1", "item1"));
comboBoxField.Items.Add(new PdfListFieldItem("Item 2", "itme2"));
comboBoxField.Items.Add(new PdfListFieldItem("Item 3", "item3"));
comboBoxField.Items.Add(new PdfListFieldItem("Item 4", "item4"));
comboBoxField.SelectedIndex = 0;
comboBoxField.Font = font;
doc.Form.Fields.Add(comboBoxField);
baseY += 25;
create a signature field
page.Canvas.DrawString("Signature Field:", font, brush1, new PointF(10, baseY));
PdfSignatureField sgnField = new PdfSignatureField(page, "sgnField");
RectangleF sgnBounds = new RectangleF(baseX, baseY, 150, 80);
sgnField.Bounds = sgnBounds;
doc.Form.Fields.Add(sgnField);
baseY += 90;
you also can create a submit button
page.Canvas.DrawString("Button:", font, brush1, new PointF(10, baseY));
RectangleF btnBounds = new RectangleF(baseX, baseY, 50, 15);
PdfButtonField buttonField = new PdfButtonField(page, "button");
buttonField.Bounds = btnBounds;
buttonField.Text = "Submit";
buttonField.Font = font;
//submit to another website
PdfSubmitAction submitAction = new PdfSubmitAction("https://www.e-iceblue.com/getformvalues.php");
submitAction.DataFormat = SubmitDataFormat.Html;
buttonField.Actions.MouseDown = submitAction;
doc.Form.Fields.Add(buttonField);
save the PDF file and return to client side
var pdfFile = "PDF/FillableForms.pdf";
//Save to file
doc.SaveToFile(pdfFile, FileFormat.PDF);
byte[] pdfBytes = System.IO.File.ReadAllBytes(pdfFile);
MemoryStream stream = new MemoryStream(pdfBytes);
//Delete the file after download
System.IO.File.Delete(pdfFile);
return new FileStreamResult(stream, "application/pdf");
2.3 Create the client for getting the PDF
We will use the MyDemo
project, so just create the generate PDF component
ng g c generatepdf
Create a service for handling API method, only one method for call the API in this case
//MyDemo.Client\src\app\services\generate-pdf.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { config } from 'src/assets/config';
/**
* ^The generate PDF service for call API to generate PDF
*/
@Injectable({
providedIn: 'root',
})
export class GeneratePDFService {
constructor(protected http: HttpClient) {
}
/**
* Generate the TP Grade Appendix PDF
* @returns
*/
public generatePDF() {
var url = config.apiUrl + "/generatePDF/generate";
return this.http.get(url, { responseType: 'blob' });
}
}
this is a simple page only a button for generate PDF:
<!-- MyDemo.Client\src\app\generatepdf\generatepdf.component.html -->
<ngx-loading
#ngxLoading
[show]="loading"
[config]="config"
[template]="loadingTemplate"
></ngx-loading>
<ng-template #loadingTemplate>
<div class="loading-class">
<h4>Please wait ...</h4>
</div>
</ng-template>
<swal #swalBox [swalVisible]="isSwalVisible"></swal>
<h1>Generate PDF</h1>
<div class="row">
<div class="col-sm-12">
<button
class="m-r-8 bg-green-700 text-light"
mat-raised-button
(click)="generate()"
>
Generate PDF
</button>
</div>
</div>
<p></p>
I uses the loading service
and swal dialog
in this page, you can find how to use them in here and here.
and implement the generate
even in ts
file
public generate() {
this.loadingService.start();
this.generatePDFService.generatePDF().subscribe(blob => {
if (blob) {
var downloadURL = window.URL.createObjectURL(new Blob([blob], { type: 'blob' }));
var link = document.createElement('a');
link.href = downloadURL;
link.download = "Demo.pdf";
link.click();
this.swalOptions.icon = 'success';
this.swalOptions.title = 'Generate PDF';
this.swalOptions.html = `The PDF has been downloaded!`;
this.swalOptions.showConfirmButton = true;
this.swalOptions.showCancelButton = false;
this.swalService.show(this.swalOptions);
}
else {
this.swalOptions.icon = 'error';
this.swalOptions.title = 'Generate Appendix';
this.swalOptions.html = `Failed to generate PDF, please find the error in server side!`;
this.swalOptions.showConfirmButton = true;
this.swalOptions.showCancelButton = false;
this.swalService.show(this.swalOptions);
}
this.loadingService.stop();
}, error => {
console.log('%c [ error ]-52', 'font-size:13px; background:pink; color:#bf2c9f;', error);
this.loadingService.stop();
});
}
}
Done!
You can find the full source code below
https://github.com/coderblog-winson/MyDemo