FastReport.OpenSource入门教程(三)
文章开始也提到导出PDF是FastReport商业版的一部份,OpenSource是不支持导出PDF的,所以我们先去下载另一个开源库PdfSharp:这也是一个强大的开源库,可以使用流式编程的风格创建PDF文件,但是我们不需要其他功能,我们只需要它画图片的功能就可以了,我们的最终目的是将FastReport.OpenSource导出的图片,用PdfSharp转换为PDF;

接下来还是在Common文件夹下新建一个报表导出类:
using FastReport.Export.Image; using PdfSharp.Drawing; using PdfSharp.Pdf; using System.Data; namespace FastReport.OpenSource.SimpleDemo.Common { public class Reportting : IDisposable { public Reportting() { _report = new Report(); _document = new PdfDocument(); } private Report _report; private PdfDocument _document; public void Prepare(string template, DataTable data) { _report.Load(template); //注册数据,NorthWind.Employees是报表模板上的ReferenceName _report.RegisterData(data, "NorthWind.Employees"); _report.Prepare(); } public void Exportting(Stream stream) { using(ImageExport imageExport = new ImageExport() { ImageFormat = ImageExportFormat.Jpeg }) { //设置导出为多张图片,否则所有内容导出为一张图片 imageExport.SaveStreams = true; //将报表以图片形式导出,并且保存到流中 _report.Export(imageExport, (Stream)null); if(imageExport.GeneratedFiles.Count > 0 ) { for(int i = 0; i < imageExport.GeneratedFiles.Count; i++) { using(MemoryStream imageStream = new MemoryStream()) { imageExport.GeneratedStreams[i].Position = 0; imageExport.GeneratedStreams[i].CopyTo(imageStream); Load(imageStream); } } } } _document.Save(stream); } private void Load(Stream stream) { PdfPage page = _document.AddPage(); XGraphics graphics = XGraphics.FromPdfPage(page); XImage image = XImage.FromStream(stream); double pointWidth = image.PointWidth; double pointHeight = image.PointHeight; page.Width = pointWidth; page.Height = pointHeight; graphics.DrawImage(image, 0, 0, pointWidth, pointHeight); } public void Dispose() { _report?.Dispose(); _document?.Dispose(); } } }
再接着就是完善我们的控制器类了,可以向前端返回PDF文件了:
using Microsoft.AspNetCore.Mvc; using FastReport.OpenSource.SimpleDemo.Common; using System.Data; namespace FastReport.OpenSource.SimpleDemo.Controllers { [Route("[controller]")] [ApiController] public class ReportController : ControllerBase { [HttpGet] [Route("[action]")] public IActionResult GetReport() { using(MemoryStream ms = new MemoryStream()) { using(Reportting report = new Reportting()) { DataTable table = new DataTable(); table.Columns.Add("FirstName"); table.Columns.Add("LastName"); table.Rows.Add("Will", "Smith"); table.Rows.Add("Tom","Cuirse"); report.Prepare("report.frx", table); report.Exportting(ms); } return base.File(ms.ToArray(), "Application/PDF"); } } } }
后端的代码已全部准备就绪,现在我们开始构建前端的代码,因为只是一个简单的示例项目,所以前端就跟后端代码放在一起了,这样还有另一个好处,就是不需要处理跨域的问题,又一次偷懒.
在项目名称上右键添加文件夹wwwroot,用来存放前端文件,在wwwroot文件夹下新建index.html,待会我们启动项目的时候手动把url改为index.html就好了,我就不去改项目启动文件的内容了,免得做的越多大家越乱.
最终建好这两个文件项目是这样的:

接下来编写前端的代码,也非常简单,我直接贴代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div>
<p>this is a webclient in server</p>
</div>
<div>
<button id="print">打印</button>
</div>
<script>
document.getElementById("print").onclick = async function () {
try {
//这里的URL对应的是LaunchSetting.json里的内容,Report是我们的控制器,GetReport是控制器方法
const pdfUrl = 'http://localhost:5051/Report/GetReport';
// 发送 GET 请求获取pdf数据
const response = await fetch(pdfUrl);
// 如果请求成功,将文件数据转换为 Blob 对象
if (response.ok) {
const blob = await response.blob();
// 创建一个新的 Blob URL
const blobUrl = URL.createObjectURL(blob);
// 在新的标签页中打开 Blob URL
window.open(blobUrl, '_blank');
} else {
console.error('Failed to fetch pdf:', response.statusText);
}
} catch (error) {
console.error('Error fetching pdf:', error);
}
};
</script>
</body>
</html>
由于我们把前后端项目放在了一起,所以我们的Program类还要添加一行使用静态文件的代码:

好,现在我们启动项目:


所以我们必须在项目启动后手动的去访问http://localhost:5051/index.html(你们的端口号可能不同,具体去看launchSetting.json,最后点击打印按扭,它就会按照我们设计好的报表模板按照我们提供的数据生成PDF传到前端,我们就可以在前端进行打印了:

好,到这里整个入门教程就告一段落了,报表模板的设计大家可以自己找一下教程,如果传数据的时候想要传业务类列表,也就是IEnumerable<Model>,而不是DataTable的话,报表模板也需要做相应的修改,具体可以参考FastReport.OpenSource开源项目的Demo
2024-04-08 13:45:37

浙公网安备 33010602011771号