在咱們開發某個系統的時候,客戶總會提出一些特定的報表需求,固定的報表格式符合他們的業務處理須要,也貼合他們的工做場景,所以咱們儘量作出符合他們實際須要的報表,這樣咱們的系統會獲得更好的認同感。本篇隨筆介紹如何基於FastReport報表工具,生成報表PDF文檔展現醫院處方箋的內容。html
以前在隨筆《在Winform開發中使用FastReport建立報表》介紹過FastReport這個強大的報表工具,雖然介紹了各類報表的處理代碼,不過主要的案例仍是官方的案例,本篇隨筆介紹基於某個醫院的處方箋的格式報表的處理。web
FastReport.Net是一款適用於Windows Forms, ASP.NET和MVC框架的功能齊全的報表分析解決方案。FastReport.Net以C#語言編寫而成並只包含可託管的代碼。它與.NET Framework 2.0以及更高版本兼容。支持在報表中添加文本、圖像、線條、形狀、語句、條形碼、矩陣、表格、RTF、選擇框等,列表報表、分組報表、主從報表、多列報表,子報表均可以實現處理。通能夠爲終端用戶提供一個報表設計器,讓用戶能夠方便的修改現有報表和建立自定義報表。json
和其餘常規的報表工具同樣,FastReport.Net報表工具也須要定義好報表模板文件,而後再基於這個報表模板進行內容的呈現,報表模板通常定義標題、報表頁眉、明細內容、頁腳等信息。瀏覽器
咱們來看看大概的需求效果,這個是處方箋的常規格式。微信
我大概須要弄個相似格式的處方箋的報表,其中處方藥須要動態生成,以及患者信息、醫生審覈簽字的地方須要動態生成,固然,二維碼,條碼等內容也須要一併根據信息動態生成出來,因爲我主要想經過PDF展現,所以使用報表工具生成PDF文檔,已經預覽或者下載便可。框架
咱們先來看看最終設計好的報表模板,在FastReport設計器裏面的效果以下所示。工具
其中,標題部分,主要在頁眉,須要展現處方列表的在數據區展現,頁腳放置一些聯繫信息等,這樣就構建了一個完整的報表模板。post
建立一個報表模板,咱們先要定義報表頁面格式,報表報表的寬度,高度是自定義的仍是標準的,還要設置它的頁邊距等信息,以下所示。this
頁邊距設置以下所示。url
因爲這個報表包含了主表信息,和明細表的信息,咱們主表動態信息,能夠經過參數的綁定方式綁定,明細表則經過綁定DataTable的方式動態處理便可。
採用參數綁定,咱們須要在報表設計器裏面定義好咱們須要的參數,以下所示。
咱們通常預先定義好相關的參數,而後綁定在模板裏面,並設置好內容的對其格式便可。
如報表頁面裏面,咱們放置了一個表格,定義好表格的行列和寬度後,雙擊表格單元格,就能夠設置表格單元格的文本內容爲對應的參數了,以下界面所示。
爲了展現每項的序號,咱們也須要使用到系統變量,如咱們須要展現下面的內容。
那麼須要定義好每項的序號,和數據字段名稱。
對於動態展現的明細列表部分,咱們須要定義一個數據源的方式,從而可讓報表模板綁定對應的字段名稱。
我根據數據表的信息,生成一個用於綁定明細列表的數據源,以下所示。
這樣咱們在代碼綁定的時候,只須要指定Detail的名稱和對應的字段名稱便可,有了這些定義,咱們能夠在報表設計中使用字段綁定了。
在數據區拖入對應的字段定義,並調整文本大小和對其,就能夠設計出明細的部分字段綁定了。
對於二維碼和條碼,咱們能夠從報表工具欄裏面拖入對應的控件,並設置對應的綁定參數和顯示內容便可(這些也能夠經過參數,運行的時候進行動態綁定)。
最後設計好的報表如開始介紹那樣,是一個完整的報表模板了。
預覽的時候,咱們能夠看到內容綁定的地方都是空白,由於咱們沒有綁定數據源的緣由,不過整個報表的格式已經出來了,大概就是咱們須要的結果。
經過上面報表模板的設計,咱們基本的前期工做就準備好了,須要的就是根據實際業務的須要,動態呈現數據了。
在綁定數據並生成PDF格式報表的時候,咱們須要先構建一個報表對象,以下代碼所示。
//生成PDF報表文檔到具體文件 Report report = new Report(); report.Load(reportPath);
因爲數據咱們是動態構建的,所以咱們須要準備參數數據源和字段數據源兩個部分,參數咱們用字典來承載,字段數據,咱們用DataTable來承載,以下所示。
//定義參數和數據格式 var dict = new Dictionary<string, object>(); var dt = DataTableHelper.CreateTable("ProductName,Quantity|int,Unit,Specification,HowTo,Frequency");
而後咱們根據系統須要填入動態的數據,以下代碼所示。
//準備數據 dict.Add("Name", info.PatientName); dict.Add("Gender", info.Gender); var age = info.BirthDate.GetAge(); dict.Add("Age", age); dict.Add("Telephone", info.Telephone); dict.Add("CreateTime", info.CreateTime); var checkDoctor = BLLFactory<User>.Instance.GetFullNameByOpenID(info.CheckDoctor); dict.Add("CheckDoctor", !string.IsNullOrEmpty(checkDoctor) ? checkDoctor : "未知"); var CheckPharmacist = BLLFactory<User>.Instance.GetFullNameByOpenID(info.CheckPharmacist); dict.Add("CheckPharmacist", !string.IsNullOrEmpty(CheckPharmacist) ? CheckPharmacist : "未知"); var SendUser = BLLFactory<User>.Instance.GetFullNameByOpenID(info.SendUser); dict.Add("SendUser", !string.IsNullOrEmpty(SendUser) ? SendUser : "未知"); var qrcode = string.Format("{0}/h5/PrescriptionDetail?id={1}", ConfigData.WebsiteDomain, info.ID); dict.Add("QrCode", qrcode); dict.Add("BarCode", info.PrescriptionNo); if(detailList != null) { foreach(var item in detailList) { var dr = dt.NewRow(); dr["ProductName"] = item.ProductName; dr["Quantity"] = item.Quantity; dr["Unit"] = item.Unit; dr["Specification"] = ""; dr["HowTo"] = item.HowTo; dr["Frequency"] = item.Frequency; dt.Rows.Add(dr); } }
最後根據上面的數據,綁定並生成PDF報表便可,以下代碼所示。
//刷新數據源 report.RegisterData(dt, "Detail"); foreach (string key in dict.Keys) { report.SetParameterValue(key, dict[key]); } //運行報表 report.Prepare(); //導出PDF報表 PDFExport export = new PDFExport(); report.Export(export, realPath); report.Dispose();
因爲這個功能咱們是在微信公衆號裏面集成的一個報表呈現,所以咱們能夠經過PDF預覽的方式,或者直接打開PDF文檔。、
若是採用PDF在線預覽方式,能夠參考我隨筆《實如今線預覽PDF的幾種解決方案》介紹的那樣,最終採用PDFJS的在線預覽方案,無論在微信端,仍是Web端都是比較不錯的效果。
若是採用PDFJS預覽方式,那麼JS代碼以下所示。
var baseUrl = "@ViewBag.WebsiteDomain/Content/JQueryTools/pdfjs/web/viewer.html"; var url = baseUrl + "?file=" + filePath;//實際地址 location.href = url;
若是是直接打開PDF,咱們咱們就直接傳遞給瀏覽器一個PDF文件路徑便可
location.href = filePath
在微信端預覽的效果以下所示。
使用FastReport報表,整體來講,工做量主要是在設計報表模板這裏,經過代碼實現數據綁定的工做反而很是簡單,只須要指定對應的參數和字段數據表便可,而報表的設計是一項精細的工做,咱們須要根據實際狀況,反覆調整格式和呈現的效果才能作到盡善盡美,不過總體來講FastReport提供了很是強大的報表設計和處理過程,使得咱們能夠在設計一些複雜報表的時候,能夠更加高效。
在選項使用FastReport報表呈現的時候,我也試過銳浪報表的處理方式,銳浪報表的總體呈現效果也是很是不錯的,這裏順便介紹一下銳浪報表的設計、運行時綁定數據源等的步驟代碼,以供參考。
首先咱們須要定義好一個報表的模板信息,和FastReport報表模板同樣,也是相似的定義方式,報表模板設計以下所示。
上面咱們能夠看到,它也是有參數綁定和字段綁定兩種方式。
實現數據綁定的代碼以下所示。
//生成PDF報表文檔到具體文件 GridExportHelper helper = new GridExportHelper(reportPath); var json = FileUtil.FileToString(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Report/Pres.json"), Encoding.UTF8); bool success = helper.ExportPdf(json, realPath, HttpContext); if (success) { result = Content(exportPdfPath);//返回Web相對路徑 } helper.Dispose();//銷燬對象
其中ExportPdf接收一個JSON字符串,實現代碼以下所示。
/// <summary> /// 導出PDF /// </summary> /// <typeparam name="T">列表對象類型</typeparam> /// <param name="list">列表對象</param> /// <param name="filePath">存儲路徑</param> /// <param name="context"></param> /// <returns></returns> public bool ExportPdf(string json, string filePath, HttpContextBase context) { //從對應文件中載入報表模板數據 Report.LoadFromFile(this.ReportPath); //加載JSON對象 Report.LoadDataFromXML(json); IGRExportOption ExportOption = Report.PrepareExport(GRExportType.gretPDF); var exportPdf = Report.ExportToBinaryObject(); Report.UnprepareExport(); var succeeded = exportPdf.SaveToFile(filePath); return succeeded; }
最後呈現的大概效果以下所示。