如何用C#将HTML Canvas元素写入PDF文档?
解决方案:将HTML Canvas图表写入PDF(C#/JS结合方案)
我来帮你解决这个把Canvas图表存入PDF的问题,根据你的需求,这里有两种可行的方案,分别对应后端C#处理和前端直接生成的场景:
方案一:前端传递Canvas数据到后端,用C#生成PDF
因为Canvas运行在客户端,服务端无法直接访问它的DOM元素,所以我们可以先在前端把Canvas转成图片数据,再传给后端,后端用C#将图片写入PDF。
步骤1:前端把Canvas转成图片数据并发送到后端
用JavaScript获取Canvas的Base64格式数据,通过HTTP请求传给后端接口:
// 获取页面上的Canvas元素(替换成你的Canvas ID) const chartCanvas = document.getElementById('your-chart-canvas'); // 将Canvas转为PNG格式的Base64数据 const canvasImageData = chartCanvas.toDataURL('image/png'); // 发送POST请求到后端API fetch('/api/CanvasToPdf', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ imageBase64: canvasImageData }) }) .then(response => response.blob()) .then(blob => { // 下载生成的PDF const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'chart-report.pdf'; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); });
步骤2:后端C#接收数据并生成PDF
这里用iTextSharp库来处理PDF生成(需要先通过NuGet安装iTextSharp包):
using iTextSharp.text; using iTextSharp.text.pdf; using Microsoft.AspNetCore.Mvc; using System.IO; [ApiController] [Route("api/[controller]")] public class CanvasToPdfController : ControllerBase { [HttpPost] public IActionResult GeneratePdf([FromBody] CanvasRequestModel request) { // 移除Base64字符串中的前缀(data:image/png;base64,) string cleanBase64 = request.ImageBase64.Replace("data:image/png;base64,", string.Empty); byte[] imageBytes = Convert.FromBase64String(cleanBase64); using (MemoryStream pdfStream = new MemoryStream()) { // 创建PDF文档 Document pdfDoc = new Document(PageSize.A4); PdfWriter.GetInstance(pdfDoc, pdfStream); pdfDoc.Open(); // 将图片字节流转为iTextSharp的Image对象 using (MemoryStream imageStream = new MemoryStream(imageBytes)) { Image chartImage = Image.GetInstance(imageStream); // 调整图片大小以适配PDF页面(边距20px) chartImage.ScaleToFit(pdfDoc.PageSize.Width - 40, pdfDoc.PageSize.Height - 40); chartImage.SetAbsolutePosition(20, 20); pdfDoc.Add(chartImage); } pdfDoc.Close(); // 返回PDF文件供下载 return File(pdfStream.ToArray(), "application/pdf", "chart-report.pdf"); } } } // 用于接收前端数据的模型类 public class CanvasRequestModel { public string ImageBase64 { get; set; } }
方案二:前端直接用JavaScript生成PDF(无需后端C#)
如果不需要后端介入,直接用前端库jsPDF就能把Canvas图表写入PDF,步骤更简单:
实现代码
先引入jsPDF库(可以通过CDN或本地安装),然后编写生成逻辑:
// 引入jsPDF(CDN方式) <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <script> function generatePdf() { const { jsPDF } = window.jspdf; const canvas = document.getElementById('your-chart-canvas'); // 创建A4尺寸的PDF文档 const pdf = new jsPDF('portrait', 'mm', 'a4'); // 计算Canvas转PDF的尺寸(px转mm:1px = 0.264583mm) const canvasWidthMm = canvas.width * 0.264583; const canvasHeightMm = canvas.height * 0.264583; const pageWidth = pdf.internal.pageSize.getWidth(); const pageHeight = pdf.internal.pageSize.getHeight(); // 计算缩放比例,确保图片适配页面 const scale = Math.min(pageWidth / canvasWidthMm, pageHeight / canvasHeightMm); const finalWidth = canvasWidthMm * scale; const finalHeight = canvasHeightMm * scale; // 让图片在页面居中 const xPos = (pageWidth - finalWidth) / 2; const yPos = (pageHeight - finalHeight) / 2; // 将Canvas添加到PDF pdf.addImage(canvas, 'PNG', xPos, yPos, finalWidth, finalHeight); // 保存PDF文件 pdf.save('chart-report.pdf'); } </script> <!-- 触发按钮 --> <button onclick="generatePdf()">下载图表PDF</button>
注意事项
- 如果Canvas内容很大,方案一中用Base64可能会有数据体积问题,此时可以改用Blob格式传递,前端用
canvas.toBlob()生成Blob,后端接收二进制数据处理。 - 方案二中jsPDF支持添加文本、多个页面等复杂内容,适合需要在前端完成完整PDF编辑的场景。
内容的提问来源于stack exchange,提问作者ahmed_khudhair
相关产品推荐
相关产品推荐

