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();
        }
    }
}
Reportting

 

  再接着就是完善我们的控制器类了,可以向前端返回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");
            }
        }
    }
}
ReportController

  后端的代码已全部准备就绪,现在我们开始构建前端的代码,因为只是一个简单的示例项目,所以前端就跟后端代码放在一起了,这样还有另一个好处,就是不需要处理跨域的问题,又一次偷懒.

在项目名称上右键添加文件夹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>
index.html

由于我们把前后端项目放在了一起,所以我们的Program类还要添加一行使用静态文件的代码:

  好,现在我们启动项目:

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

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

2024-04-08 13:45:37

posted @ 2024-04-08 13:46  Gx小猩猩  阅读(980)  评论(0)    收藏  举报