日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用FastReport报表工具生成报表PDF文档

發(fā)布時(shí)間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用FastReport报表工具生成报表PDF文档 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在我們開發(fā)某個(gè)系統(tǒng)的時(shí)候,客戶總會(huì)提出一些特定的報(bào)表需求,固定的報(bào)表格式符合他們的業(yè)務(wù)處理需要,也貼合他們的工作場景,因此我們盡可能做出符合他們實(shí)際需要的報(bào)表,這樣我們的系統(tǒng)會(huì)得到更好的認(rèn)同感。本篇隨筆介紹如何基于FastReport報(bào)表工具,生成報(bào)表PDF文檔展示醫(yī)院處方箋的內(nèi)容。

之前在隨筆《在Winform開發(fā)中使用FastReport創(chuàng)建報(bào)表》介紹過FastReport這個(gè)強(qiáng)大的報(bào)表工具,雖然介紹了各種報(bào)表的處理代碼,不過主要的案例還是官方的案例,本篇隨筆介紹基于某個(gè)醫(yī)院的處方箋的格式報(bào)表的處理。

FastReport.Net是一款適用于Windows Forms, ASP.NET和MVC框架的功能齊全的報(bào)表分析解決方案。FastReport.Net以C#語言編寫而成并只包含可托管的代碼。它與.NET Framework 2.0以及更高版本兼容。支持在報(bào)表中添加文本、圖像、線條、形狀、語句、條形碼、矩陣、表格、RTF、選擇框等,列表報(bào)表、分組報(bào)表、主從報(bào)表、多列報(bào)表,子報(bào)表都可以實(shí)現(xiàn)處理。通可以為終端用戶提供一個(gè)報(bào)表設(shè)計(jì)器,讓用戶可以方便的修改現(xiàn)有報(bào)表和創(chuàng)建自定義報(bào)表。

1、定義報(bào)表模板

和其他常規(guī)的報(bào)表工具一樣,FastReport.Net報(bào)表工具也需要定義好報(bào)表模板文件,然后再基于這個(gè)報(bào)表模板進(jìn)行內(nèi)容的呈現(xiàn),報(bào)表模板一般定義標(biāo)題、報(bào)表頁眉、明細(xì)內(nèi)容、頁腳等信息。

我們來看看大概的需求效果,這個(gè)是處方箋的常規(guī)格式。

?我大概需要弄個(gè)類似格式的處方箋的報(bào)表,其中處方藥需要?jiǎng)討B(tài)生成,以及患者信息、醫(yī)生審核簽字的地方需要?jiǎng)討B(tài)生成,當(dāng)然,二維碼,條碼等內(nèi)容也需要一并根據(jù)信息動(dòng)態(tài)生成出來,由于我主要想通過PDF展示,因此使用報(bào)表工具生成PDF文檔,已經(jīng)預(yù)覽或者下載即可。

我們先來看看最終設(shè)計(jì)好的報(bào)表模板,在FastReport設(shè)計(jì)器里面的效果如下所示。

?其中,標(biāo)題部分,主要在頁眉,需要展示處方列表的在數(shù)據(jù)區(qū)展示,頁腳放置一些聯(lián)系信息等,這樣就構(gòu)建了一個(gè)完整的報(bào)表模板。

創(chuàng)建一個(gè)報(bào)表模板,我們先要定義報(bào)表頁面格式,報(bào)表報(bào)表的寬度,高度是自定義的還是標(biāo)準(zhǔn)的,還要設(shè)置它的頁邊距等信息,如下所示。

?頁邊距設(shè)置如下所示。

?

由于這個(gè)報(bào)表包含了主表信息,和明細(xì)表的信息,我們主表動(dòng)態(tài)信息,可以通過參數(shù)的綁定方式綁定,明細(xì)表則通過綁定DataTable的方式動(dòng)態(tài)處理即可。

采用參數(shù)綁定,我們需要在報(bào)表設(shè)計(jì)器里面定義好我們需要的參數(shù),如下所示。

?我們一般預(yù)先定義好相關(guān)的參數(shù),然后綁定在模板里面,并設(shè)置好內(nèi)容的對(duì)其格式即可。

如報(bào)表頁面里面,我們放置了一個(gè)表格,定義好表格的行列和寬度后,雙擊表格單元格,就可以設(shè)置表格單元格的文本內(nèi)容為對(duì)應(yīng)的參數(shù)了,如下界面所示。

?

?為了展示每項(xiàng)的序號(hào),我們也需要使用到系統(tǒng)變量,如我們需要展示下面的內(nèi)容。

?那么需要定義好每項(xiàng)的序號(hào),和數(shù)據(jù)字段名稱。

?對(duì)于動(dòng)態(tài)展示的明細(xì)列表部分,我們需要定義一個(gè)數(shù)據(jù)源的方式,從而可以讓報(bào)表模板綁定對(duì)應(yīng)的字段名稱。

?我根據(jù)數(shù)據(jù)表的信息,生成一個(gè)用于綁定明細(xì)列表的數(shù)據(jù)源,如下所示。

?這樣我們在代碼綁定的時(shí)候,只需要指定Detail的名稱和對(duì)應(yīng)的字段名稱即可,有了這些定義,我們可以在報(bào)表設(shè)計(jì)中使用字段綁定了。

?在數(shù)據(jù)區(qū)拖入對(duì)應(yīng)的字段定義,并調(diào)整文本大小和對(duì)其,就可以設(shè)計(jì)出明細(xì)的部分字段綁定了。

對(duì)于二維碼和條碼,我們可以從報(bào)表工具欄里面拖入對(duì)應(yīng)的控件,并設(shè)置對(duì)應(yīng)的綁定參數(shù)和顯示內(nèi)容即可(這些也可以通過參數(shù),運(yùn)行的時(shí)候進(jìn)行動(dòng)態(tài)綁定)。

?最后設(shè)計(jì)好的報(bào)表如開始介紹那樣,是一個(gè)完整的報(bào)表模板了。

?

預(yù)覽的時(shí)候,我們可以看到內(nèi)容綁定的地方都是空白,因?yàn)槲覀儧]有綁定數(shù)據(jù)源的原因,不過整個(gè)報(bào)表的格式已經(jīng)出來了,大概就是我們需要的結(jié)果。

?

2、生成報(bào)表PDF內(nèi)容

通過上面報(bào)表模板的設(shè)計(jì),我們基本的前期工作就準(zhǔn)備好了,需要的就是根據(jù)實(shí)際業(yè)務(wù)的需要,動(dòng)態(tài)呈現(xiàn)數(shù)據(jù)了。

在綁定數(shù)據(jù)并生成PDF格式報(bào)表的時(shí)候,我們需要先構(gòu)建一個(gè)報(bào)表對(duì)象,如下代碼所示。

//生成PDF報(bào)表文檔到具體文件
Report report = new Report();
report.Load(reportPath);

由于數(shù)據(jù)我們是動(dòng)態(tài)構(gòu)建的,因此我們需要準(zhǔn)備參數(shù)數(shù)據(jù)源和字段數(shù)據(jù)源兩個(gè)部分,參數(shù)我們用字典來承載,字段數(shù)據(jù),我們用DataTable來承載,如下所示。

//定義參數(shù)和數(shù)據(jù)格式
var dict = new Dictionary<string, object>();
var dt = DataTableHelper.CreateTable("ProductName,Quantity|int,Unit,Specification,HowTo,Frequency");

然后我們根據(jù)系統(tǒng)需要填入動(dòng)態(tài)的數(shù)據(jù),如下代碼所示。

//準(zhǔn)備數(shù)據(jù)
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);
}
}


最后根據(jù)上面的數(shù)據(jù),綁定并生成PDF報(bào)表即可,如下代碼所示。


//刷新數(shù)據(jù)源
report.RegisterData(dt, "Detail");
foreach (string key in dict.Keys)
{
report.SetParameterValue(key, dict[key]);
}

//運(yùn)行報(bào)表
report.Prepare();

//導(dǎo)出PDF報(bào)表
PDFExport export = new PDFExport();
report.Export(export, realPath);
report.Dispose();


由于這個(gè)功能我們是在微信公眾號(hào)里面集成的一個(gè)報(bào)表呈現(xiàn),因此我們可以通過PDF預(yù)覽的方式,或者直接打開PDF文檔。、

如果采用PDF在線預(yù)覽方式,可以參考我隨筆《實(shí)現(xiàn)在線預(yù)覽PDF的幾種解決方案》介紹的那樣,最終采用PDFJS的在線預(yù)覽方案,不管在微信端,還是Web端都是比較不錯(cuò)的效果。

如果采用PDFJS預(yù)覽方式,那么JS代碼如下所示。

var baseUrl = "@ViewBag.WebsiteDomain/Content/JQueryTools/pdfjs/web/viewer.html";
var url = baseUrl + "?file=" + filePath;//實(shí)際地址
location.href = url;

如果是直接打開PDF,我們我們就直接傳遞給瀏覽器一個(gè)PDF文件路徑即可

location.href = filePath

在微信端預(yù)覽的效果如下所示。

使用FastReport報(bào)表,總體來說,工作量主要是在設(shè)計(jì)報(bào)表模板這里,通過代碼實(shí)現(xiàn)數(shù)據(jù)綁定的工作反而非常簡單,只需要指定對(duì)應(yīng)的參數(shù)和字段數(shù)據(jù)表即可,而報(bào)表的設(shè)計(jì)是一項(xiàng)精細(xì)的工作,我們需要根據(jù)實(shí)際情況,反復(fù)調(diào)整格式和呈現(xiàn)的效果才能做到盡善盡美,不過整體來說FastReport提供了非常強(qiáng)大的報(bào)表設(shè)計(jì)和處理過程,使得我們可以在設(shè)計(jì)一些復(fù)雜報(bào)表的時(shí)候,可以更加高效。

3、采用其他報(bào)表設(shè)計(jì)-銳浪報(bào)表設(shè)計(jì)展現(xiàn)

在選項(xiàng)使用FastReport報(bào)表呈現(xiàn)的時(shí)候,我也試過銳浪報(bào)表的處理方式,銳浪報(bào)表的整體呈現(xiàn)效果也是非常不錯(cuò)的,這里順便介紹一下銳浪報(bào)表的設(shè)計(jì)、運(yùn)行時(shí)綁定數(shù)據(jù)源等的步驟代碼,以供參考。

首先我們需要定義好一個(gè)報(bào)表的模板信息,和FastReport報(bào)表模板一樣,也是類似的定義方式,報(bào)表模板設(shè)計(jì)如下所示。

?

上面我們可以看到,它也是有參數(shù)綁定和字段綁定兩種方式。

實(shí)現(xiàn)數(shù)據(jù)綁定的代碼如下所示。

//生成PDF報(bào)表文檔到具體文件
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相對(duì)路徑
}
helper.Dispose();//銷毀對(duì)象

其中ExportPdf接收一個(gè)JSON字符串,實(shí)現(xiàn)代碼如下所示。

/// <summary>
/// 導(dǎo)出PDF
/// </summary>
/// <typeparam name="T">列表對(duì)象類型</typeparam>
/// <param name="list">列表對(duì)象</param>
/// <param name="filePath">存儲(chǔ)路徑</param>
/// <param name="context"></param>
/// <returns></returns>
public bool ExportPdf(string json, string filePath, HttpContextBase context)
{
//從對(duì)應(yīng)文件中載入報(bào)表模板數(shù)據(jù)
Report.LoadFromFile(this.ReportPath);

//加載JSON對(duì)象
Report.LoadDataFromXML(json);

IGRExportOption ExportOption = Report.PrepareExport(GRExportType.gretPDF);
var exportPdf = Report.ExportToBinaryObject();
Report.UnprepareExport();

var succeeded = exportPdf.SaveToFile(filePath);
return succeeded;
}

最后呈現(xiàn)的大概效果如下所示。


總結(jié)

以上是生活随笔為你收集整理的使用FastReport报表工具生成报表PDF文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。