水晶報表 動態載入圖片 簽名
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
水晶報表動態控制圖片顯示 Changing pictures dynamically in Crystal Report
專案需要在報表中根據條件動態顯示不同的簽名
查找了好多解決方案,一個比較簡單的方案:
本人試驗是可以用的,但是正如作者所講,基於CR XI 獨立版本實現。CR9和CR10都無此功能。
就是說,用獨立CR XI 完整版本做,可以實現效果,但是一旦在VS2005 專案中使用,這個效果是出不來的.
後來在網路上找到幻想天空文章http://hi.baidu.com/awming520/blog/item/3a6ccc2ab082a924d52af11f.html
水晶報表動態載入圖片分為資料庫圖片和本地圖片。
首先建立水晶報表rpt檔案,方法還是採用xsd資料集的方式,簡便容易操作,記得將資料集中的相關欄位設為你想要在報表中呈現的欄位。比如說在內容左邊加入一個圖片,就將相應的圖片欄位拖放過去。能不能直接在水晶報表上新增一個圖片然後修改?我做了幾次實驗,好像都不得要領,所以還是放棄,走最老式的方式,先在資料庫中建立一個準備在水晶報表中使用到的欄位的表,然後再通過這張表建立資料集xsd檔案,再通過資料集建立水晶報表。雖然方法繞了路,但是絕對是可行的。
通過資料集建立dataset
DataSet1.pictureTabDataTable pt = new DataSet1.pictureTabDataTable(); DataSet1TableAdapters.pictureTabTableAdapter da = new DataSet1TableAdapters.pictureTabTableAdapter(); da.Fill(pt); CrystalReport1 cr = new CrystalReport1(); cr.SetDataSource((DataTable)pt); this.crystalReportViewer1.ReportSource = cr;
表名叫做pictureTab,因此建立的資料集有表pictureTabDataTable類和介面卡pictureTabTableAdapter,奇怪的是前面的名稱空間,著實沒有找到,不過無關要害。
通過資料庫建立Dataset
SqlConnection conn = new SqlConnection("Data Source=(Local);Initial Catalog=MyDB;User ID=sa;Password=yamato"); SqlDataAdapter da = new SqlDataAdapter("select * from pictureTab where name ='e'", conn); DataSet ds = new DataSet(); da.Fill(ds, "NewTable"); CrystalDecisions.CrystalReports.Engine.ReportDocument doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument(); doc.Load(@"C:/Documents and Settings/jiez/桌面/CrystalReportsApplication1/CrystalReportsApplication1/CrystalReport1.rpt"); doc.SetDataSource(ds.Tables["NewTable"]); this.crystalReportViewer1.ReportSource = doc;
這個其實也沒什麼好說的,只是修改了一下報表載入的方式而已。
厲害的來了,本地圖片載入
DataSet ds = new DataSet(); ds.Tables.Add("NewTable"); ds.Tables[0].Columns.Add("id", Type.GetType("System.Int32")); ds.Tables[0].Columns.Add("picture", Type.GetType("System.Byte[]")); ds.Tables[0].Columns.Add("name", Type.GetType("System.String")); string picPath = @"C:/Documents and Settings/jiez/My Documents/My Pictures/logo.jpg"; AddOneRow(ds.Tables["NewTable"], "1", picPath, "Jackey"); CrystalDecisions.CrystalReports.Engine.ReportDocument doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument(); doc.Load(@"C:/Documents and Settings/jiez/桌面/CrystalReportsApplication1/CrystalReportsApplication1/CrystalReport1.rpt"); doc.SetDataSource(ds.Tables["NewTable"]); this.crystalReportViewer1.ReportSource = doc; public void AddOneRow(DataTable tbl, string c1, string c2, string c3) { FileStream fs = new FileStream(c2, FileMode.Open); BinaryReader br = new BinaryReader(fs); DataRow row = tbl.NewRow(); row[0] = c1; row[2] = c3; row[1] = br.ReadBytes((int)br.BaseStream.Length); tbl.Rows.Add(row); }
這裡自己建立了一個dataset,並且往裡面添加了資料,都是自己進行設定,這樣靈活性就很高了,要注意的是這裡的資料讀取採用的是BinaryReader直接就用二進位制的方式進行了讀取。
是可以實現的.
註釋:1.AddOneRow 函式中並沒有關閉資料流 fs1.Close();fs2.Close();
public void AddOneRow(DataTable tbl, string c1, string c2, string c3) { FileStream fs1 = new FileStream(c2, FileMode.Open); FileStream fs2 = new FileStream(c3, FileMode.Open); BinaryReader br1 = new BinaryReader(fs1); BinaryReader br2 = new BinaryReader(fs2); DataRow row = tbl.NewRow(); row[1] = br1.ReadBytes((int)br1.BaseStream.Length); row[2] = br2.ReadBytes((int)br2.BaseStream.Length); tbl.Rows.Add(row); fs1.Close(); fs2.Close(); } protected void Page_Load(object sender, EventArgs e) { //sql SqlConnection conn = new SqlConnection(PublicVar.strCon_SHATDB); SqlDataAdapter da = new SqlDataAdapter("select * from stamp ", conn); DataSet ds = new DataSet(); da.Fill(ds, "NewTable"); //儲存過程取得ds SqlParameter[] parms = new SqlParameter[1]; parms[0] = new SqlParameter("@id", SqlDbType.Int); parms[0].Value = 2; //部門 DataSet ds = new DataSet(); ds = DataAccess.DataAccessSHDB.GetTableByStore("test3", parms).DataSet; //DataSet ds = new DataSet(); string picPath1 = @"C:/test/1.jpg"; string picPath2 = @"C:/test/2.jpg"; AddOneRow(ds.Tables[0], "1", picPath1, picPath2); CrystalDecisions.CrystalReports.Engine.ReportDocument doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument(); doc.Load(@"C:/test/1.rpt");//報表已經設定簽名的image欄位 doc.SetDataSource(ds.Tables[0]); CrystalReportViewer1.ReportSource = doc; CrystalReportViewer1.DataBind(); }
後來我根據思路重構了一下
報表的dataset中設定需要簽名的欄位一定要是IMAGE 路徑儲存在資料中
public void AddOneRow(DataTable tbl, string c1, string c2, string c3, string c4, string c5,string c6,string c7) { //FileStream fs1 = new FileStream(c2, FileMode.Open); //FileStream fs2 = new FileStream(c3, FileMode.Open); //BinaryReader br1 = new BinaryReader(fs1); //BinaryReader br2 = new BinaryReader(fs2); //DataRow row = tbl.NewRow(); //row[0] = c1; //row[0] = br1.ReadBytes((int)br1.BaseStream.Length); //row[1] = br2.ReadBytes((int)br2.BaseStream.Length); //fs1.Close(); //fs2.Close(); //tbl.Rows.Add(row); for (int i = 0; i < tbl.Rows.Count; i++) //如果在頭部那麼第一行就夠了 如果在尾部最後一行就OK 如果在Group 中就必須所有行 { FileStream fs1 = new FileStream(c1, FileMode.Open); FileStream fs2 = new FileStream(c2, FileMode.Open); FileStream fs3 = new FileStream(c3, FileMode.Open); FileStream fs4 = new FileStream(c4, FileMode.Open); FileStream fs5 = new FileStream(c5, FileMode.Open); FileStream fs6 = new FileStream(c6, FileMode.Open); FileStream fs7 = new FileStream(c7, FileMode.Open); BinaryReader br1 = new BinaryReader(fs1); BinaryReader br2 = new BinaryReader(fs2); BinaryReader br3 = new BinaryReader(fs3); BinaryReader br4 = new BinaryReader(fs4); BinaryReader br5 = new BinaryReader(fs5); BinaryReader br6 = new BinaryReader(fs6); BinaryReader br7 = new BinaryReader(fs7); tbl.Rows[i][0] = br1.ReadBytes((int)br1.BaseStream.Length); tbl.Rows[i][1] = br2.ReadBytes((int)br2.BaseStream.Length); tbl.Rows[i][2] = br3.ReadBytes((int)br3.BaseStream.Length); tbl.Rows[i][3] = br4.ReadBytes((int)br4.BaseStream.Length); tbl.Rows[i][4] = br5.ReadBytes((int)br5.BaseStream.Length); tbl.Rows[i][5] = br6.ReadBytes((int)br6.BaseStream.Length); tbl.Rows[i][6] = br7.ReadBytes((int)br7.BaseStream.Length); fs1.Close(); fs2.Close(); fs3.Close(); fs4.Close(); fs5.Close(); fs6.Close(); fs7.Close(); //tbl.Rows.Add(row); } } private void CrystalReportDataBind(int id) { SqlParameter[] parms = new SqlParameter[1]; parms[0] = new SqlParameter("@id", SqlDbType.Int); parms[0].Value = id; //部門 DataSet ds = new DataSet(); ds = DataAccess.DataAccessSHDB.GetTableByStore("project", parms).DataSet; //以下部分是讀取本地圖片 string strURL ="select u.stamp_path from taskline tl left join users u on tl.UserID=u.[ID] where taskcode='"+lbl_taskcode.Text+"' and TurnTo='1' AND Result='Y' "; string[] picPath=new string[7]; for(int i=0;i<=6;i++) { if (string.IsNullOrEmpty(PublicFunction.StringGetValue(strURL + " and taskline=" + (i + 1), 0)) == false) //取得已經審批人的本地簽名地址 { //picPath[i] = "@" + PublicFunction.StringGetValue(strURL + " and taskline=" + (i + 1), 0); //string urlPath = Server.MapPath("..//Reports//"+PublicFunction.StringGetValue(strURL + " and taskline=" + (i + 1), 0));//無法動態解析伺服器地址 picPath[i] = PublicFunction.StringGetValue(strURL + " and taskline=" + (i + 1), 0); //儲存本地地址 } else { switch (i) { case 0: picPath[i] = @"C:/stamp/空白1.jpg"; //空白地址頁面 防止程序同時被佔用 break; case 1: picPath[i] = @"C:/stamp/空白2.jpg"; break; case 2: picPath[i] = @"C:/stamp/空白3.jpg"; break; case 3: picPath[i] = @"C:/stamp/空白4.jpg"; break; case 4: picPath[i] = @"C:/stamp/空白5.jpg"; break; case 5: picPath[i] = @"C:/stamp/空白6.jpg"; break; case 6: picPath[i] = @"C:/stamp/空白7.jpg"; break; } } } //string picPath1 = @"C:/test/2.jpg"; //string picPath2 = @"C:/test/2.jpg"; AddOneRow(ds.Tables[0], picPath[0], picPath[1], picPath[2], picPath[3], picPath[4], picPath[5], picPath[6]); CrystalDecisions.CrystalReports.Engine.ReportDocument doc = new CrystalDecisions.CrystalReports.Engine.ReportDocument(); string reportPath = Server.MapPath("..//Reports//project.rpt"); //doc.Load(@"C:/test/1.rpt"); doc.Load(reportPath); doc.SetDataSource(ds.Tables[0]); CrystalReportViewer1.ReportSource = doc; CrystalReportViewer1.DataBind(); }
效果圖: