Wednesday, April 4, 2012

Display image from file path in Crystal .NET Report


พบกันเช่นเคยครับ เพื่อตอบข้อสงสัยของหลายๆ คำถาม ถามถึงการแสดงรูปภาพบน Crystal Report
บทความนี้เป็นการค้นหาคำตอบให้ท่าน โดยการแสดงรูปภาพจาก path files 

ข้อมูล path files ของรูปภาพ ถูกเก็บเป็น String บน SQL base เพื่ออ้างอิง ไฟล์รูปภาพบน Folder Photo ใน Folder Application ของเรา

การดึงรูปภาพที่เป็นไฟล์ มาแสดงบน Crystal Report ได้โดยการต้องแปลงข้อมูลไฟล์ภาพ (*.gif,*.jpg, ฯลฯ) เป็น ข้อมูล Binary


เริ่มกันเลยครับ...

ระบบรายงานข้อมูลพนักงาน (รายงานแบบลูกทุ่งๆไม่ว่ากันนะครับ)


ออกแบบระบบ

1. New Project เป็น WindowsApplication (C#ลาก CrystalReportViewer วางบน Form1
2. New Item เพื่อออกแบบ Dataset
3. เลือก Templates: เป็น Dataset
4. คลิกขวาบน Dataset Dataset Designer :=> Add => DataTable
5. เปลี่ยนชื่อ DataTable1 => imEmployees
6.เพิ่ม Column โดยคลิกขวาบน Table imEmployees :=>Add =>Column
7.Add Column ดังรูป Set DataType ของ Emp_ID, FName,LName เป็น System.String
8. DataType ของ Photo เป็น Byte Array:  System.Byte[]
9. เลือก Systen.Byte
10. set เป็น Byte Array โดยพิมพ์ [] ต่อท้าย Systen.Byte ดังรูป
11. เพิ่ม Crystal Report Item เข้ามาใน Project
12. คลิก OK
13. Data Source เลือก ADO.Net DataSets ดังรูป
14.

15. Design Report เรียบร้อย
16. ลาก Field Photo เข้ามาในรายงาน ปรับรายงานตามต้องการ
17.ทดสอบ Previous report
18. ยังไม่มีรูปครับ แสดงข้อมูลตามที่ระบบสุ่มให้
19.เนื่องจากเราต้องการดึงข้อมูลใน Table Employees ใน base Northwind เราต้อง update ค่าใน Field PhotoPath เป็น Photo/ชื่อรูปภาพ.jpg (Photo/*.jpg =เป็น path เก็บรูปภาพของเรา)
20. สร้าง Folder Photo ใน Folder Bin แล้ว Copy รูปไปวางไว้ครับ
21.วางรูปใน Folder Photo
ออกแบบระบบเรียบร้อย...

เขียนโปรแกรมกันเลยครับ


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Data.SqlClient;
using System.IO;


namespace WinCSCrystal_Img
{
    public partial class Form1 : Form
    {
                DataSet dsImg = new DataSet(); // ผ่านข้อมูลให้ Crystal Report
        SqlDataReader  sdr;// อ่านข้อมูลจาก sql base

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string sql = "select EmployeeID, FirstName, LastName,PhotoPath from Employees";

            SqlConnection cnn = new SqlConnection("Server=(local);uid=xx;pwd=xxxx;database=Northwind;");
            cnn.Open();

            //สร้าง temp table Add column ตาม DataSet = imEmployees
            DataTable dt = new DataTable("imEmployees");// ชื่อ Table imEmployees
            dt.Columns.Add(new DataColumn("Emp_ID"typeof(string)));
            dt.Columns.Add(new DataColumn("FName"typeof(string)));
            dt.Columns.Add(new DataColumn("LName"typeof(string)));
            dt.Columns.Add(new DataColumn("Photo"typeof(System.Byte[]))); // DataType ของ Photo เป็นSystem.Byte[]

            dsImg.Tables.Add(dt);// Add table เข้าไปใน DataSet           

            SqlDataAdapter da = new SqlDataAdapter(sql, cnn);
            sdr = da.SelectCommand.ExecuteReader();
           
            if (sdr.HasRows)
            {

                while (sdr.Read())
                {
                    string path = Application.StartupPath + "\\" + sdr["PhotoPath"].ToString();

                    FileStream FilStr = new FileStream(path, FileMode.Open);// เปิด file แบบ Stream เพื่ออ่านเป็นBinary
                    BinaryReader BinRed = new BinaryReader(FilStr);

                    DataRow dr = this.dsImg.Tables["imEmployees"].NewRow(); //เพิ่ม Rows ใหม่
                    // Add ข้อมูลที่อ่านจาก SQL Base ใส่เข้าไปแต่ละ Rows ของ Temp Table
                    dr["Emp_ID"] = sdr["EmployeeID"];
                    dr["FName"] = sdr["FirstName"];
                    dr["LName"] = sdr["LastName"];
                    // Column Photo ใส่ข้อมูล  Binary
                    dr["Photo"] = BinRed.ReadBytes((int)BinRed.BaseStream.Length);

                    dsImg.Tables["imEmployees"].Rows.Add(dr); //Add Row เข้าไปใน Temp Table

                    // คืน memory ให้ OS
                    FilStr.Close(); //ปิด FileStream
                    BinRed.Close(); //ปิด BinaryReader
                }

                // คืน memory ให้ OS
                sdr.Close();
                cnn.Close();
                               
                CrystalReport1 crp = new CrystalReport1();

                crp.SetDataSource(dsImg.Tables["imEmployees"]);
                crystalReportViewer1.ReportSource = crp;
                crystalReportViewer1.Refresh();
            }
               
        }
    }
}

 
ทดสอบรายงาน

รายงานข้อมูลพนักงาน
 
ใน Table Employees มี Field Photo ซึ่ง DataType เป็น image ซึ่งสามารถออกรายงานบน Crystal Report ได้
ทันที ไม่ต้องแปลงไฟล์เหมือนวิธีดึงรูปจาก Path ดังรูป


Summary


หวังว่าบทความนี้สามารถตอบข้อสงสัย ผู้อ่านได้บ้างไม่มากก็น้อย และหวังเป็นอย่างยิ่งว่า ท่านจะสนุกกับการเดินบนเส้นทางของ โลก.Net ต่อไป

หากเกิดข้อผิดพลาดประการได ขอน้อมรับคำแนะนำ และพร้อมแก้ไขในครั้งต่อๆ ไป...

เอามาลงให้แล้วครับตามคำสัญญา
 
ใน Picture Object กำหนด Formula ของ Property Graphic Location ให้เป็นดังรูปครับ
 
ปล. p_pic เป็น path ที่เก็บรูปอยู่ใน DB ครับ
Application.StartupPath = full path ที่ app. run อยู่ 
ฉนั้น ถ้ารูปภาพของเราเก็บอยู่ที่เดี่ยวกับ app. (*.exe) ของ เวลาอ้าง pathจะใช้
Application.StartupPath +"\\"
ถ้ามี folder ย่อยจะต่อด้วยชื่อ folder เช่น folder ย่อยชื่อ photo เราจะเอาชื่อfolder ย่อยกับชื่อเก็บบันทึกลง base
:>
photo\001.jpg
photo\002.jpg
photo\003.jpg
เป็นต้น
จะใช้งานอ้างแบบนี้
Application.StartupPath +\\+SqlReader.Item("pic").ToString()
 
ถ้าต้องการใช้ path = sdr.Item("PicPicPath").ToString
 
field "PicPicPath" ต้องเก็บค่า full path
เช่นต้องบันทึกใน base =>
c:\photo\001.jpg
c:\photo\002.jpg
c:\photo\003.jpg

Schema DataSet ตาม=> 10. set เป็น Byte Array โดยพิมพ์ [] ต่อท้าย Systen.Byte ดังรูป
 กำหนด Type เป็น Systen.Byte[] ใหมครับ
ถ้าถูกต้องแล้ว คงต้องขอดู code แล้วครับ

No comments:

Post a Comment