
node.js + express + docker + mysql + jwt 實現用戶管理restful api
設置項目名稱和位置,并將框架設置為 .NET 8。
打開 Nuget 包管理器,搜索并安裝 PuppeteerSharp 包。
現在,我們將創建一個服務類來處理轉換過程。在?Services?文件夾中添加新的?HtmlToService.cs?類文件。
using PuppeteerSharp;
using PuppeteerSharp.Media;
namespace HtmlToPdfWebApi.Services;
public class HtmlToPdfService
{
private readonly IBrowser _browser;
private readonly PdfOptions _pdfOptions;
public HtmlToPdfService()
{
var browserFetcher = new BrowserFetcher();
browserFetcher.DownloadAsync().GetAwaiter().GetResult();
_browser = Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
}).GetAwaiter().GetResult();
_pdfOptions = new PdfOptions
{
Format = PaperFormat.A4,
MarginOptions = new MarginOptions
{
Top = "10mm",
Right = "10mm",
Bottom = "10mm",
Left = "10mm",
}
};
}
public async Task ToFile(string htmlContent, string outputFilePath)
{
using var page = await _browser.NewPageAsync();
await page.SetContentAsync(htmlContent);
await page.PdfAsync(outputFilePath, _pdfOptions);
await page.CloseAsync();
}
public async Task<byte[]> ToByteArray(string htmlContent)
{
using var page = await _browser.NewPageAsync();
await page.SetContentAsync(htmlContent);
var data = await page.PdfDataAsync(_pdfOptions);
await page.CloseAsync();
return data;
}
}
在構造函數中,初始化和配置 IBrowser 和 PdfOptions。
BrowserFetcher 用于異步下載必要的瀏覽器二進制文件。
它以無外設模式(無 GUI)啟動瀏覽器,以優化服務器環境的性能。
Pdf選項設置為定義 PDF 格式 (A4) 和邊距(所有邊長 10 毫米)。
此方法將 HTML 內容轉換為 PDF 文件,并將其保存到指定的文件路徑。
它會在瀏覽器中創建一個新頁面,并將頁面內容設置為提供的 HTML。
它使用預定義的選項生成 PDF,并將其保存到指定的文件路徑。
此方法將 HTML 內容轉換為 PDF,并將其作為字節數組返回。
與?ToFile()?方法類似,它會創建一個新頁面并設置 HTML 內容。
它不是保存到文件中,而是將 PDF 數據檢索為字節數組。
在 Controllers 文件夾中創建一個新的 InvoiceController.cs 類文件。
將?HtmlToPdfService?注入到構造函數中:
namespace HtmlToPdfWebApi.Controllers;
[Route("api/invoice")]
[ApiController]
public class InvoiceController : ControllerBase
{
private readonly HtmlToPdfService htmlToPdfService;
public InvoiceController(HtmlToPdfService htmlToPdfService)
{
this.htmlToPdfService = htmlToPdfService;
}
}
現在,讓我們定義將轉換為 PDF 的 HTML 內容:
private string htmlContent = @"<!DOCTYPE html>
<html lang=""en"">
<head>
<meta charset=""UTF-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
<title>Invoice</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.invoice-box {
max-width: 800px;
margin: 20px auto;
padding: 30px;
border: 1px solid #eee;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}
.invoice-box table {
width: 100%;
line-height: inherit;
text-align: left;
border-collapse: collapse;
}
.invoice-box table td {
padding: 8px;
vertical-align: top;
}
.invoice-box table tr td:nth-child(2) {
text-align: right;
}
.invoice-box table tr.top table td {
padding-bottom: 20px;
}
.invoice-box table tr.top table td.title {
font-size: 45px;
line-height: 45px;
color: #333;
}
.invoice-box table tr.information table td {
padding-bottom: 40px;
}
.invoice-box table tr.heading td {
background: #eee;
border-bottom: 1px solid #ddd;
font-weight: bold;
}
.invoice-box table tr.item td {
border-bottom: 1px solid #eee;
}
.invoice-box table tr.item.last td {
border-bottom: none;
}
.invoice-box table tr.total td:nth-child(2) {
border-top: 2px solid #eee;
font-weight: bold;
}
</style>
</head>
<body>
<div class=""invoice-box"">
<table>
<tr class=""top"">
<td colspan=""2"">
<table>
<tr>
<td class=""title"">
<h2>Invoice</h2>
</td>
<td>
Invoice #: 123<br>
Created: January 1, 2024<br>
Due: January 15, 2024
</td>
</tr>
</table>
</td>
</tr>
<tr class=""information"">
<td colspan=""2"">
<table>
<tr>
<td>
Billing to:<br>
John Doe<br>
1234 Main St.<br>
Springfield, IL 62704
</td>
<td>
Company Name<br>
info@company.com
</td>
</tr>
</table>
</td>
</tr>
<tr class=""heading"">
<td>Item</td>
<td>Price</td>
</tr>
<tr class=""item"">
<td>Website design</td>
<td>$300.00</td>
</tr>
<tr class=""item"">
<td>Hosting (3 months)</td>
<td>$75.00</td>
</tr>
<tr class=""item"">
<td>Domain name (1 year)</td>
<td>$10.00</td>
</tr>
<tr class=""item last"">
<td>SEO Optimization</td>
<td>$150.00</td>
</tr>
<tr class=""total"">
<td></td>
<td>Total: $535.00</td>
</tr>
</table>
</div>
</body>
</html>
";
接下來,添加一個將返回 PDF 文件的新操作方法:
[HttpGet("pdf")]
public async Task<FileResult> GetPdf(CancellationToken cancellationToken)
{
var pdfContent = await htmlToPdfService.ToByteArray(htmlContent);
return File(pdfContent, "application/pdf", "invoice.pdf");
}
我們需要將?HtmlToPdfService?注冊到服務容器。
打開Program.cs文件并將?HtmlToPdfService?注冊為單一實例:
using HtmlToPdfWebApi.Services;
var builder = WebApplication.CreateBuilder(args);
// register HtmlToPdfService as singleton
builder.Services.AddSingleton(new HtmlToPdfService());
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapControllers();
app.Run();
我們需要使用 new 關鍵字顯式初始化類。這將確保 PuppeteerSharp 在應用程序啟動期間下載必要的瀏覽器二進制文件。
現在,讓我們按 [F5] 鍵運行應用程序。大搖大擺的頁面將打開。
執行終結點,然后單擊“響應”部分中的“下載文件”鏈接:
PDF文件將被下載:
文章轉自微信公眾號@架構師老盧
node.js + express + docker + mysql + jwt 實現用戶管理restful api
nodejs + mongodb 編寫 restful 風格博客 api
表格插件wpDataTables-將 WordPress 表與 Google Sheets API 連接
手把手教你用Python和Flask創建REST API
使用 Django 和 Django REST 框架構建 RESTful API:實現 CRUD 操作
ASP.NET Web API快速入門介紹
2024年在線市場平臺的11大最佳支付解決方案
完整指南:如何在應用程序中集成和使用ChatGPT API
選擇AI API的指南:ChatGPT、Gemini或Claude,哪一個最適合你?