利用FastReport傳遞圖片引數,在報表上展示簽名資訊

2022-10-14 18:02:27

在一個專案中,客戶要求對報表中的簽名進行仿手寫的簽名處理,因此我們原先只是顯示相關人員的姓名的地方,需要採用手寫方式簽名,我們的報表是利用FastReport處理的,在利用楷體處理的時候,開發展示倒是正常效果,不過實際上在伺服器執行的時候,出來的確實正規的宋體格式,相應的字型都已經安裝,不過還是沒有生效。因此採用變通的方式,在對應簽名的地方採用圖片的格式顯示,實際效果達到要求。本篇隨筆介紹這個過程,利用FastReport傳遞圖片引數,在報表上展示簽名資訊的處理。

1、報表上的設計處理

例如我們要在報表落款的附近記錄相關人員的名字,因此採用簽名的顯示方式會比較合理。

 

因此設計相關的報表,本來想是採用文字的方式,變化字型的方式來快捷實現的

 

 不過在報表是在伺服器上生成圖片的方式,導致正常出來的圖片,卻沒有變化字型,導致出來的是正常的宋體格式。 

  

 因此考慮使用圖片的格式方式來處理。在其中放置Picture控制元件,如下所示。

 

調整好Picture控制元件的高度和寬度,讓它在設計的空白上合適的展示即可。 

為了實現圖片格式的顯示,我們需要在報表的圖片控制元件的BeforePrint事件中解析資料(來自傳遞引數),資料格式為Base64字串(從Byte資料轉換),如下程式碼所示。

namespace FastReport
{
  public class ReportScript
  {

    private void shopDoctorImg_BeforePrint(object sender, EventArgs e)
    {
      var img = GetImage("ShopDoctor");
      if(img != null){
        shopDoctorImg.Image=img;  
      }
    }   
    private void tiaopeiImg_BeforePrint(object sender, EventArgs e)
    {    
      var img = GetImage("Tiaopei");
      if(img != null){
        tiaopeiImg.Image=img;  
      }
    }       

    private void CheckDoctorImg_BeforePrint(object sender, EventArgs e)
    {
      var img = GetImage("CheckDoctor");
      if(img != null){
        CheckDoctorImg.Image=img;  
      }
    }

    private void CheckPharmacistImg_BeforePrint(object sender, EventArgs e)
    {       
      var img = GetImage("CheckPharmacist");
      if(img != null){
        CheckPharmacistImg.Image=img;  
      }
    }
    private Image GetImage(string signName)
    {         
      Image img = null;
      string imgStr = (string)Report.GetParameterValue(signName);
      if(!string.IsNullOrEmpty(imgStr))
      {
        byte[] imgData= Convert.FromBase64String(imgStr);
        using(MemoryStream ms = new MemoryStream(imgData))
        {
          img = System.Drawing.Image.FromStream(ms);            
        }
      }
      return img;
    }
        
  }
}

其中主要注意的是,我們傳遞的圖片資料需要採用Base64String的格式才能正常傳遞和展示。 

2、報表傳遞圖片資料

完成了報表的設計處理,我們剩下的就是在實際的報表中傳遞對應的引數資料了。

我們把簽名圖片,放在相對的目錄上,如下所示。

 

 然後編寫一個公用的讀取圖片為Base64String的函數處理,如下所示。

        //通過姓名獲取簽名圖片的Base64
        private string GetSignImage(string signName)
        {
            var result = "";
            string imagePath = Path.Combine(baseDir, $"Report/signs/{signName}.png");
            if (File.Exists(imagePath))
            {
                var stream = FileUtil.FileToStream(imagePath);
                var image = FileUtil.StreamToBytes(stream);
                if (image != null)
                {
                    result = Convert.ToBase64String(image);
                }
            }
            return result;
        }

接著就是根據對應的報表進行載入,並設定相關的引數進行傳遞給報表即可,如下測試程式碼所示。

    //生成PDF報表檔案到具體檔案
    Report report = new Report();
    report.Load(reportFile);

    //定義引數和資料格式
    var dict = new Dictionary<string, object>();
    #region 測試資料來源
    dict.Add("Name", "張三");
    dict.Add("Gender", "");
    dict.Add("Age", 32);
    dict.Add("Telephone", "18620292076");
    dict.Add("CreateTime", "2019-10-13 22:30:15");
    dict.Add("CheckDoctor", GetSignImage("張醫生"));//"張醫生"
    dict.Add("CheckPharmacist", GetSignImage("張醫生")); //"李藥師"
    dict.Add("SendUser", "王小姐");
    dict.Add("QrCode", "http://www.iqidi.com");
    dict.Add("BarCode", "1234567890");

    //圖片檔案
    dict.Add("ShopDoctor", GetSignImage("張醫生"));
    dict.Add("Tiaopei", GetSignImage("張醫生"));
    dict.Add("Fayao", GetSignImage("王小姐"));    
    #endregion
    
    report.RegisterData(dt, "Detail");
    foreach (string key in dict.Keys)
    {
        report.SetParameterValue(key, dict[key]);
    }

    //執行報表
    report.Prepare();    

由於我們的報表,最終是生成PDF或者圖片的方式,方便客戶進行線上查詢的,因此可以選擇PDF或者圖片的格式生成。

    //執行報表
    report.Prepare();    
    
    //匯出PDF報表
    //PDFExport export = new PDFExport();

    //多個圖片匯出
    int count = 1;
    string firstFileName = exportImgPath.Replace(".png", "");
    foreach (PageBase item in report.Pages)
    {
        string fileName = string.Format("{0}_{1}.png", firstFileName,  count);
        exportImgPath = fileName;
        //Resolution= 300可以提高解析度
        report.Export(new ImageExport() { PageRange = PageRange.Current, CurPage = count, Resolution= 300 }, fileName);
        count++;
    }

最後生成的圖片格式如下所示,順利吧簽名的圖片貼在對應的單元格中即可。