Tag: .Net

  • เรียนรู้เบื้องต้นกับการใส่ลายน้ำ(Watermark)ให้กับเอกสาร PDF ของเราด้วย iTextSharp

                   ในบทความนี้เราก็ยังคงอยู่กับเรื่องการทำภาพลายน้ำอย่างต่อเนื่องจาก EP. ที่แล้วที่พูดถึงการทำข้อความลายน้ำบนภาพที่เราทำการอัพโหลด ถ้าใครยังไม่ได้อ่านสามารถตามไปอ่านกันได้ ที่นี่ นะคะแต่สำหรับ EP. นี้เราจะขอเปลี่ยนบรรยากาศไปทำ ลายน้ำบนไฟล์ PDF โดยใช้เครื่องมือ iTextSharp กันบ้าง เผื่อว่าผู้อ่านบางท่านที่อาจจะกำลังใช้งาน iTextSharp ในการจัดทำไฟล์ PDF อยู่พอดี และอยากจะลองใส่ลายน้ำให้กับงานเอกสารของท่านดูบ้าง จะได้สามารถนำวิธีการนี้ไปประยุกต์ใช้กับงานของตนได้ไม่ทางใดก็ทางหนึ่งนะคะ โดยตัวอย่างที่จะนำมาแนะนำกันจะมีทั้งแบบลายน้ำที่เป็นข้อความ และลายน้ำที่เป็นภาพค่ะ นอกจากนี้ก็ยังมีทั้งแบบที่เป็นการทำภาพลายน้ำทับไฟล์เดิมที่มีอยู่ และแบบที่ทำภาพลายน้ำและบันทึกเป็นไฟล์ใหม่ค่ะ ผู้อ่านจะได้ลองในหลายๆวิธี และสามารถเลือกไปปรับใช้ให้เหมาะกับงานของแต่ละท่านได้เพื่อไม่ให้เป็นการเสียเวลา งั้นเรามาเริ่มทำภาพลายน้ำบนงานเอกสาร PDF ของเรากันเลยดีกว่าค่ะ

    แบบที่ 1 : การสร้างลายน้ำแบบข้อความ ซึ่งวิธีการนี้ จะมีการทำ Template ต้นฉบับของลายน้ำแบบข้อความไว้ก่อน และเมื่อต้องการทำไฟล์ลายน้ำ จะต้องทำการอ่านไฟล์ลายน้ำจากต้นแบบมาจัดทำลายน้ำบนไฟล์ที่ต้องการได้ ดังนี้ค่ะ

    1.1 ระบุ Library เพิ่มเติม

    using iTextSharp.text;
    using iTextSharp.text.pdf;
    using System.IO;

    1.2 สร้างเมธอดในการสร้าง Template ลายน้ำต้นฉบับ เพื่อใช้ในการทำลายน้ำให้กับไฟล์ PDF ที่ต้องการ

            ////กรณียังไม่เคยสร้างหรือมี Template มาก่อน ให้เรียกใช้งาน CreateTemplate("ข้อความที่ต้องการให้แสดงในเทมเพลต",พาธที่จะสร้างไฟล์เทมเพลตดังกล่าว) 
            public void CreateTemplate(string watermarkText, string targetFileName)
            {
                var document = new Document();
    
                ////ระบุพาธที่ต้องการสร้างไฟล์เทมเพลต
                var pdfWriter = PdfWriter.GetInstance(document, new FileStream(targetFileName, FileMode.Create));
                ///ระบุค่าต่างๆเกี่ยวกับตัวอักษรที่จะแสดงผลในเทมเพลตลายน้ำที่สร้างขึ้น
                var font = new Font(Font.FontFamily.HELVETICA, 60, Font.NORMAL, BaseColor.LIGHT_GRAY);
                document.Open();
    
                ////ระบุค่าข้อความ และค่าต่างๆให้กับลายน้ำที่ต้องการ
                ColumnText.ShowTextAligned(pdfWriter.DirectContent, Element.ALIGN_CENTER, new Phrase(watermarkText, font), 300, 400, 45);
                document.Close();
            }

    ตัวอย่าง ไฟล์ PDF ของ Template ลายน้ำที่ได้จากการเรียกใช้งานเมธอด CreateTemplate ข้างต้น

    1.3 สร้างเมธอดในการจัดทำลายน้ำข้อความให้กับไฟล์ PDF จาก template ลายน้ำต้นฉบับ

    public void AddTextWatermark(string sourceFilePath, string watermarkTemplatePath, string targetFilePath)
            {
                ///ระบุพาธไฟล์ต้นทางที่ต้องการทำข้อความลายน้ำ
                var pdfReaderSource = new PdfReader(sourceFilePath);
                ///ระบุพาธไฟล์ปลายทางที่ต้องการบันทึกไฟล์แบบมีลายน้ำ
                var pdfStamper = new PdfStamper(pdfReaderSource, new FileStream(targetFilePath, FileMode.Create));
    
                ///ระบุพาธของไฟล์ต้นแบบลายน้ำที่จัดทำไว้
                var pdfReaderTemplate = new PdfReader(watermarkTemplatePath);
                var page = pdfStamper.GetImportedPage(pdfReaderTemplate, 1);
    
                ///ทำการวนลูปเพื่อทำลายน้ำให้กับไฟล์ PDF ทีละหน้า
                for (var i = 0; i < pdfReaderSource.NumberOfPages; i++)
                {
                    ///ระบุตำแหน่งในการแสดงผลลายน้ำกับเนื้อหาในไฟล์ PDF กรณีนี้คือวางไว้ใต้เนื้อหา แต่หากต้องการให้อยู่บนเนื้อหาให้เปลี่ยนเป็น GetOverContent แทน 
                    var content = pdfStamper.GetUnderContent(i + 1);
                    content.AddTemplate(page, 0, 0);
                }
    
                pdfStamper.Close();
                pdfReaderTemplate.Close();
            }

    1.4 เรียกใช้งานเมธอดเพื่อทำลายน้ำให้กับไฟล์ PDF ที่ต้องการ(กรณีนี้สมมุติให้เป็นการกดปุ่มเพื่อเรียกใช้งานเมธอดดังกล่าว)

     protected void btnGenWatermark_Click(object sender, EventArgs e)
            {
                 ////กำหนด Path ของไฟล์ PDF ต้นทางที่ต้องการทำลายน้ำ กรณีที่ gen จาก iTextSharp สามารถนำมาประยุกต์ใช้โดยเอาพาธดังกล่าวมาใช้เป็น strSourcePath ได้เลย
                string strSourcePath = HttpContext.Current.Server.MapPath("~/PDF/File/PDFDocument.pdf");
    
                 ////สร้างตัวแปรชื่อไฟล์ PDF ที่จะบันทึกใหม่ในชื่อตัวแปร genName
                string genName = Guid.NewGuid().ToString() + ".pdf";
    
                 ////กรณียังไม่เคยสร้างหรือมี Template มาก่อนให้เรียกใช้งาน CreateTemplate("ข้อความที่ต้องการให้แสดงในเทมเพลต",templatePath)  ทั้งชื่อไฟล์เทมเพลตใหม่ที่จะบันทึก
                string templatePath = HttpContext.Current.Server.MapPath("~/PDF/TemplateWatermarkPDF/" + genName);
    
                 ////ระบุพาธปลายทางที่ต้องการบันทึกไฟล์แบบมีลายน้ำพร้อมทั้งชื่อไฟล์ใหม่ที่จะบันทึก
                string targetPath = HttpContext.Current.Server.MapPath("~/PDF/WatermarkPDF/" + genName);
    
                 ////ตรวจสอบว่ามีไฟล์ดังกล่าวอยู่จริงตามที่อยู่ที่ระบุไว้หรือไม่
                if( File.Exists(strSourcePath))
                { 
                     ////กรณียังไม่เคยสร้างหรือมี Template มาก่อน ให้เรียกใช้งาน CreateTemplate("ข้อความที่ต้องการให้แสดงในเทมเพลต",พาธที่จะสร้างไฟล์เทมเพลตดังกล่าว) 
                    CreateTemplate("Copyrights (c) 2023", templatePath);
    
                     ////เรียกใช้งานเมธอดในการสร้างข้อความลายน้ำตามเทมเพลตที่มี(ตามพาธที่ระบุ) โดยส่งค่าที่อยู่ของไฟล์ต้นทาง พาธเทมเพลตที่ต้องการทำลายน้ำ และพาธปลายทางที่ต้องการบันทึกไฟล์แบบมีลายน้ำ
                    AddTextWatermark(strSourcePath, templatePath, targetPath);
                }
            }

    ตัวอย่างผลลัพธ์

    หมายเหตุ : 

    1. บางครั้งอาจพบว่าการใช้ GetUnderContent อาจทำให้ข้อความลายน้ำโดนเนื้อหาบดบังได้ในบางกรณี จนอาจจะต้องใช้ GetOverContent แทนดังเช่นตัวอย่างต่อไปนี้ 

    แต่สำหรับเนื้อหาในไฟล์ PDF โดยทั่วไปแล้ว สามารถใช้งาน GetUnderContent ได้ตามปกติ เพื่อไม่ให้ข้อความลายน้ำบดบังเนื้อหาในเอกสาร

    แบบที่ 2 การสร้างลายน้ำแบบรูปภาพให้กับเอกสาร PDF โดยจะขอยกตัวอย่างให้ดู 2 แบบนะคะ คือแบบที่สร้างลายน้ำบนไฟล์ PDF ใหม่ และแบบที่สร้างลายน้ำบนไฟล์ต้นทางเดิมค่ะ 

    2.1 แบบสร้างลายน้ำบนไฟล์ใหม่ โดยการสร้างเมธอด AddImageWatermark

        public void AddImageWatermark(string sourceFilePath, string watermarkImagePath, string targetFilePath)
            {
                ///ระบุพาธไฟล์ต้นทางที่ต้องการทำภาพลายน้ำ
                var pdfReader = new PdfReader(sourceFilePath);
    
                ///ระบุพาธไฟล์ปลายทางที่ต้องการบันทึกไฟล์แบบมีภาพลายน้ำ
                var pdfStamper = new PdfStamper(pdfReader, new FileStream(targetFilePath, FileMode.Create));
    
                ///ระบุพาธของไฟล์ภาพที่ต้องการนำมาทำภาพลายน้ำ
                var image = iTextSharp.text.Image.GetInstance(watermarkImagePath);
                image.SetAbsolutePosition(200, 400);
    
                ///ทำการวนลูปเพื่อทำภาพลายน้ำให้กับไฟล์ PDF ทีละหน้า
                for (var i = 0; i < pdfReader.NumberOfPages; i++)
                {
                    var content = pdfStamper.GetUnderContent(i + 1);
                    content.AddImage(image);
                }
    
                pdfStamper.Close();
            }

    วิธีเรียกใช้งาน (กรณีนี้สมมุติให้เป็นการกดปุ่มเพื่อเรียกใช้งานเมธอดดังกล่าว)

            protected void btnGenWatermark_Click(object sender, EventArgs e)
            {
                ////กำหนด Path ของไฟล์ภาพที่ต้องการทำลายน้ำ
                string strWaterMark = HttpContext.Current.Server.MapPath("~/images/clientpreview.png");
                
    ////ระบุ Path ของไฟล์ PDF ต้นทางที่ต้องการทำลายน้ำ string strSourcePath = HttpContext.Current.Server.MapPath("~/PDF/File/job_apply_form.pdf");
    ////สร้างตัวแปรชื่อไฟล์ PDF ที่จะบันทึกใหม่ในชื่อตัวแปร genName string genName = Guid.NewGuid().ToString() + ".pdf";
    ////ระบุพาธปลายทางที่ต้องการบันทึกไฟล์แบบมีลายน้ำพร้อมทั้งชื่อไฟล์ใหม่ที่จะบันทึก string targetPath = HttpContext.Current.Server.MapPath("~/PDF/WatermarkPDF/" + genName);
    ////ตรวจสอบว่ามีไฟล์ภาพลายน้ำ และไฟล์ PDF ต้นทางดังกล่าวอยู่จริงตามที่อยู่ที่ระบุไว้หรือไม่ if (File.Exists(strWaterMark) && File.Exists(strSourcePath)) { AddImageWatermark(strSourcePath, strWaterMark, targetPath); } }

    2.2 แบบสร้างลายน้ำบนไฟล์เดิม โดยการสร้างเมธอด AddImageWatermarkInExistingFile

     private void AddImageWatermarkInExistingFile(string sourceFilePath,string watermarkImagePath )
            {
                 ///อ่านค่าจากพาธไฟล์ต้นทางที่ต้องการทำภาพลายน้ำ
                byte[] bytes = File.ReadAllBytes(sourceFilePath);
    
                 ///ระบุพาธของไฟล์ภาพที่ต้องการนำมาทำภาพลายน้ำ
                var img = iTextSharp.text.Image.GetInstance(watermarkImagePath);
    
                img.SetAbsolutePosition(200, 400);
                PdfContentByte waterMark;
    
                using (MemoryStream stream = new MemoryStream())
                {
                     ///ทำภาพลายน้ำในไฟล์ต้นทางที่ต้องการทำภาพลายน้ำ
                    PdfReader reader = new PdfReader(bytes);
                    using (PdfStamper stamper = new PdfStamper(reader, stream))
                    {
                        ///ทำการวนลูปเพื่อทำภาพลายน้ำให้กับไฟล์ PDF ทีละหน้า
                        int pages = reader.NumberOfPages;
                        for (int i = 1; i <= pages; i++)
                        {
                            waterMark = stamper.GetUnderContent(i);
                            waterMark.AddImage(img);
                        }
                    }
                    bytes = stream.ToArray();
                }
                File.WriteAllBytes(sourceFilePath, bytes);
            }

    วิธีเรียกใช้งาน (กรณีนี้สมมุติให้เป็นการกดปุ่มเพื่อเรียกใช้งานเมธอดดังกล่าว)

            protected void btnGenWatermark_Click(object sender, EventArgs e)
            {
                ////กำหนด Path ของไฟล์ภาพที่ต้องการทำลายน้ำ
                string strWaterMark = HttpContext.Current.Server.MapPath("~/images/clientpreview.png");
    
                ////ระบุ Path ของไฟล์ PDF ต้นทางที่ต้องการทำลายน้ำ
                string strSourcePath = HttpContext.Current.Server.MapPath("~/PDF/File/job_apply_form.pdf");
    
                ////สร้างตัวแปรชื่อไฟล์ PDF ที่จะบันทึกใหม่ในชื่อตัวแปร genName
                string genName = Guid.NewGuid().ToString() + ".pdf";
    
                 ////ตรวจสอบว่ามีไฟล์ภาพลายน้ำ และไฟล์ PDF ต้นทางดังกล่าวอยู่จริงตามที่อยู่ที่ระบุไว้หรือไม่
                if (File.Exists(strWaterMark) && File.Exists(strSourcePath))
                {
                    AddImageWatermarkInExistingFile(strSourcePath,strWaterMark);
                 }
            }
    

    ตัวอย่างผลลัพธ์

    หมายเหตุ :
    1. ทั้งสองวิธีข้างต้นจะให้ผลลัพธ์ของภาพลายน้ำแบบเดียวกัน แต่ต่างกันตรงที่ไฟล์ที่บันทึกภาพลายน้ำ โดยแบบแรกจะสร้างเป็นไฟล์ใหม่ แต่แบบที่สองจะบันทึกลงบนไฟล์เดิม

    2. ในการใช้ภาพทำภาพลายน้ำ อาจจะต้องระวังเกี่ยวกับขนาดภาพที่นำมาใช้ในการแสดงผล และอาจต้องทดสอบการจัดวางตำแหน่งของภาพ เพื่อให้ภาพลายน้ำดังกล่าวออกมาสวยงาม และตรงกับความต้องการในการใช้งาน เพราะหากใช้ภาพที่ใหญ่หรือเล็กเกินไป อาจทำให้ไม่เหมาะกับการนำมาใช้งานได้

               ซึ่งทั้งหมดนี้ก็เป็นเพียงวิธีเบื้องต้นในการสร้างภาพลายน้ำด้วย iTextSharp เท่านั้น เราอาจจะต้องลองผิดลองถูก ประยุกต์วิธีการนำไปใช้ไปด้วยกัน และหวังว่าบทความนี้จะเป็นประโยชน์กับผู้อ่านเพื่อให้แต่ละท่านสามารถนำวิธีดังกล่าวไปประยุกต์ใช้เพิ่มเติมกับงานพัฒนาที่ท่านกำลังทำอยู่ หรือหากผู้อ่านท่านใดมีข้อเสนอแนะสามารถให้คำแนะนำมาได้นะคะ ทางเรายินดีรับฟังทุกข้อเสนอแนะ เพื่อเป็นการต่อยอดความรู้ร่วมกันนะคะ แล้วพบกันใหม่ในบทความหน้า และขอบคุณที่ติดตามกันนะคะ ^^

    แหล่งอ้างอิง

  • จะทำอย่างไรให้สามารถดึงข้อมูลมาแสดงผลด้วย Progress bar โดยใช้ .Net (C#)

              จากบทความก่อนหน้านี้ ผู้เขียนได้แนะนำเกี่ยวกับ Progress bar และวิธีการใช้งานเบื้องต้นกันไปแล้ว ซึ่งใครที่ยังไม่ได้อ่าน สามารถอ่านเพิ่มเติมได้ ที่นี่ มาถึงในบทความนี้ ผู้เขียนจึงขอนำความรู้ดังกล่าวมาต่อยอดประยุกต์ใช้กับการทำงานจริงที่มีการดึงข้อมูลตอน Runtime มาแสดงผลด้วย Progress bar โดยผู้เขียนจะไม่ขอลงรายละเอียดในส่วนของการสร้างสไตล์ชีทและการกำหนดค่าต่างๆแล้ว แต่จะเน้นในส่วนของการดึงข้อมูลมาแสดงแทน โดยผู้เขียนจะพยายามยกตัวอย่างให้เห็นหลายแนว เพื่อให้ผู้อ่านเห็นภาพในการนำไปใช้มากขึ้น ซึ่งแต่ละแบบจะต้องทำอย่างไรบ้าง มาดูกันเลยค่ะ

    แบบแถบละสี

    1. ดึงข้อมูลจากฐานข้อมูล และจัดเตรียม Tag Html ที่จะใช้ในการแสดงผล
        private void getData()
        {
            ////////////////////เป็นการสมมุติการดึงข้อมูลมาใส่ Datatable ที่ชื่อว่า dtProgress ซึ่งเป็นจำนวนของผลไม้แต่ละชนิด
    
            StringBuilder strProgress = new StringBuilder();
            DataTable dtProgress = new DataTable();
            dtProgress.Columns.AddRange(new DataColumn[2] { 
                             new DataColumn("Percent", typeof(int)),
                            new DataColumn("Name",typeof(string))});
    
            dtProgress.Rows.Add(25, "Orange");
            dtProgress.Rows.Add(56, "Grape");
            dtProgress.Rows.Add(45, "Mango");
            dtProgress.Rows.Add(100, "Banana");
          
          ////////////////////เป็นการวนลูปค่าเพื่อสร้างแท็ก html ในการแสดงผลแถบ Progress bar
             int i = 0;
             for ( i = 0; i <= dtProgress.Rows.Count -1; i++) 
             {
             
         ////////////////////เป็นการแสดงชื่อผลไม้แต่ละชนิดบนแถบ Progress bar
                strProgress.Append("<h3 class=\"progress-title\">" + dtProgress.Rows[i]["Name"] + "</h3>");
                strProgress.Append("<div class=\"progress-outer\">");
                strProgress.Append("<div class=\"progress\">");
    
         ////////////////////เป็นการแสดงกำหนดขนาดให้กับแถบสี Progress bar ตามข้อมูล % ในแถวที่วน และมีการ ดึงค่าสไตล์ชีทจากการเรียกใช้ฟังก์ชั่น getCss()
    
    ตามเงื่อนไขของจำนวน % ด้วย
                strProgress.Append("<div class=\"progress-bar progress-bar-striped " + getCss(int.Parse(dtProgress.Rows[i]["Percent"].ToString())) + " \" style=\"width:" + dtProgress.Rows[i]["Percent"] + "%;\"></div>");
    
    
         ////////////////////แสดงจำนวน % ของแต่ละแถบ Progress bar
    
                strProgress.Append("<div class=\"progress-value\"><span>" + dtProgress.Rows[i]["Percent"] + "</span>%</div>");
                strProgress.Append("</div></div>");
             }
    
         ////////////////////นำค่า Tag Html ที่เตรียมไว้ มาแสดงผลด้วย Literal
    
             ltrProgressBar.Text = strProgress.ToString();
    
        }

    2. เมธอดในการแปลงค่าสไตล์ชีทเพื่อปรับสีตามจำนวนที่ส่งมาเป็นพารามิเตอร์

    private string getCss(int Percent)
        {
            string ReturnResult = "";
    
            if (Percent >= 0 && Percent <= 25) 
            {
                ReturnResult = "progress-bar-danger";
            }
            else if (Percent > 25&& Percent <= 50) 
            {
                ReturnResult = "progress-bar-warning"; 
            }
            else if (Percent > 50 && Percent <= 75)
            {
                ReturnResult = "progress-bar-info";
            }
            else if (Percent > 75 && Percent <= 100)
            {
                ReturnResult = "progress-bar-success";
            }
            return ReturnResult;
        }

    จากโค้ดข้างต้นจะเป็นการกำหนดสไตล์ชีทที่จะใช้ ซึ่งจะขึ้นอยู่กับจำนวนค่า % ที่ส่งมาเป็นพารามิเตอร์ โดยจะแบ่งออกเป็น 4 ช่วง

    • สีแดง ช่วงตั้งแต่ 0 – 25 %
    • สีส้ม ช่วงตั้งแต่ 26 – 50 %
    • สีฟ้า ช่วงตั้งแต่ 51 – 75 %
    • สีเขียว ช่วงตั้งแต่ 76 – 100 %

    ตัวอย่างการเรียกใช้งาน

        protected void Page_Load(object sender, EventArgs e)
        {
            getData();
        }

    ผลลัพธ์

    แบบหลายสีในแถบเดียวกัน(แบบที่ 1)

              โดยในตัวอย่างนี้ จะเป็นการแสดงข้อมูลจำนวนผลไม้เป็น % รวมในแถบ Progress bar เดียวกัน ซึ่งจะแยกตามสี และมีบอกจำนวนรวมถึงชื่อผลไม้ให้ทราบ อีกทั้งยังแสดงจำนวนรวมของผลไม้ทุกชนิดด้วย โดยมีวิธีการทำ ดังนี้ค่ะ

    1. ดึงข้อมูลจากฐานข้อมูล และจัดเตรียม Tag Html ที่จะใช้ในการแสดงผล
        private void getMultiFruitColorData()
        {
            StringBuilder strProgress = new StringBuilder();
            DataTable dtProgress = new DataTable();
            dtProgress.Columns.AddRange(new DataColumn[2] { 
                             new DataColumn("Percent", typeof(int)),
                            new DataColumn("Name",typeof(string))});
            dtProgress.Rows.Add(25, "Orange");
            dtProgress.Rows.Add(12, "Grape");
            dtProgress.Rows.Add(7, "Mango");
            dtProgress.Rows.Add(25, "Banana");
    
            int i = 0;
            int percent = 0;
            string CssStr = "";
            int Total = 0;
            
                strProgress.Append("<h3 class=\"progress-title\">Multiple-fruits</h3>");
                strProgress.Append("<div class=\"progress-outer\">");
                strProgress.Append("<div class=\"progress\">");
            for (i = 0; i <= dtProgress.Rows.Count - 1; i++)
            {
                percent = int.Parse(dtProgress.Rows[i]["Percent"].ToString());
    
    
    ////////////////////คำนวณผลรวม % ของผลไม้ทุกชนิดตามการวนรอบที่จะแสดงในแถบ Progress bar
    
                Total += percent;
                switch (i) 
                {
                    case 0: CssStr = "progress-bar-danger"; break;
                    case 1: CssStr = "progress-bar-warning"; break;
                    case 2: CssStr = "progress-bar-info"; break;
                    case 3: CssStr = "progress-bar-success"; break;
                }
    
    ////////////////////เป็นการแสงค่า % ของผลไม้แต่ละชนิดในแถบ Progress bar เดียวกัน โดยแสดงชื่อผลไม้ และจำนวน % ของผลไม้แต่ละชนิดด้วย
    
                strProgress.Append("<div class=\"progress-bar progress-bar-striped " + CssStr + "\" style=\"width:" + percent + "%;\">" + dtProgress.Rows[i]["Name"] + "(" + percent + "%)</div>");
               
            }  
    
     ////////////////////เป็นการแสงผลรวม % ของผลไม้ทุกชนิดในแถบ Progress bar
    
            strProgress.Append("<div class=\"progress-value\"><span>" + Total + "</span>%</div></div>");
            strProgress.Append("</div></div>");
    
            ltrProgressBar.Text = strProgress.ToString();
    
        }
    

              จากโค้ดตัวอย่างข้างต้น จะเห็นว่าการสร้างแท็ก Html จะแตกต่างจากแบบแรก คือจะมีการสร้างใน <div class=\”progress\”> เดียวกัน ซึ่งมีหลักการคล้ายกับการสร้าง Progress bar อย่างง่ายหลายสีในแถบเดียวกันที่เคยกล่าวไว้แล้วในบทความก่อนหน้านั่นเอง

    ผลลัพธ์

    แบบหลายสีในแถบเดียวกันและแสดงหลายแถบ Progress Bar(แบบที่ 2)

              ในตัวอย่างนี้ เป็นการแสดงผลแถบสีแยกตามช่วงของข้อมูลบน Progress bar แต่ละแถบ โดยการแสดงผลจะแบ่งสีตามปริมาณข้อมูลในแต่ละช่วง ดังนี้

    สีแดง ช่วงตั้งแต่ 0 – 25 % สีส้ม ช่วงตั้งแต่ 26 – 50 % สีฟ้า ช่วงตั้งแต่ 51 – 75 % สีเขียว ช่วงตั้งแต่ 76 – 100 %

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

    1. ดึงข้อมูลจากฐานข้อมูล และจัดเตรียม Tag Html ที่จะใช้ในการแสดงผล
        private void getMultiColorData()
        {
            StringBuilder strProgress = new StringBuilder();
            DataTable dtProgress = new DataTable();
            dtProgress.Columns.AddRange(new DataColumn[2] { 
                             new DataColumn("Percent", typeof(int)),
                            new DataColumn("Name",typeof(string))});
    
            dtProgress.Rows.Add(25, "Orange");
            dtProgress.Rows.Add(56, "Grape");
            dtProgress.Rows.Add(45, "Mango");
            dtProgress.Rows.Add(100, "Banana");
    
            int i = 0;
            int j = 0;
            int maxRange = 0;
            int percent = 0;
            for (i = 0; i <= dtProgress.Rows.Count - 1; i++)
            {
                percent= int.Parse(dtProgress.Rows[i]["Percent"].ToString());
    
    
    ////////////////////วนเพื่อสร้าง Progress bar ใหม่ในผลไม้แต่ละชนิด
    
                strProgress.Append("<h3 class=\"progress-title\">" + dtProgress.Rows[i]["Name"] + "</h3>");
                strProgress.Append("<div class=\"progress-outer\">");
                strProgress.Append("<div class=\"progress\">");
                maxRange = 0;
    
    ////////////////////คำนวณหาว่าค่าของ % ตกอยู่ในช่วงใด 1-4(เนื่องจากแบ่งออกเป็นช่วงละ 25 % และรวมเป็น 100%)
    
    
                if (percent >= 0 && percent <= 25)
                {
                    maxRange = 1;
                }
                else if (percent > 25 && percent <= 50)
                {
                    maxRange = 2;
                }
                else if (percent > 50 && percent <= 75)
                {
                    maxRange = 3;
                }
                else if (percent > 75 && percent <= 100)
                {
                    maxRange = 4;
                }
    
    ////////////////////วนลูปเพื่อแสดงผลสีในแต่ละช่วงบน Progress bar โดยมีการเรียกใช้งานเมธอด getCssRange()
    
                for (j = 1; j <= maxRange; j++)
                {
                    strProgress.Append(getCssRange(percent, j, maxRange));
                 }
                strProgress.Append("<div class=\"progress-value\"><span>" + dtProgress.Rows[i]["Percent"] + "</span>%</div></div>");
                strProgress.Append("</div></div>");
            }
    
            ltrProgressBar.Text = strProgress.ToString();
    
        }

    2. สร้างเมธอดที่ใช้ในการสร้างแท็ก Html ในการแสดงผลแถบสี ซึ่งในส่วนของกระบวนการคำนวณแถบสีจะไม่ขอลงในรายละเอียด แต่แสดงไว้ให้เห็นภาพการทำงานหลักๆเท่านั้น ดังนี้ค่ะ

        private string getCssRange(int Percent,int Range,int MaxRange)
        {
            string ReturnResult = "";
    
            switch (Range)
            {
                case 1:
                    if (MaxRange > Range)
                        ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-danger\" style=\"width:25%;\"></div>";
    
                    else 
                    {
                        Percent = Percent >= 25 ? 25 : Percent - (25 * (Range - 1));
                    ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-danger\" style=\"width:" + Percent + "%;\"></div>";
                    }
                    break;
                case 2:
                    if (MaxRange > Range)
                        ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-warning\" style=\"width:25%;\"></div>";
    
                    else
                    {
                        Percent = Percent >= 50 ? 50 : Percent - (25 * (Range - 1));
                        ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-warning\" style=\"width:" + Percent + "%;\"></div>";
                    }
                   
                    break;
    
                case 3:
                    if (MaxRange > Range)
                        ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-info\" style=\"width:25%;\"></div>";
    
                    else
                    {
                        Percent = Percent >= 75 ? 75 : Percent- (25* (Range-1));
                        ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-info\" style=\"width:" + Percent + "%;\"></div>";
                    }
                     break;
    
                case 4:
    
                     if (Percent==100)
                         ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-success\" style=\"width:25%;\"></div>";
                     else
                     {
                         Percent =   Percent - (25 * (Range - 1));
                         ReturnResult = "<div class=\"progress-bar progress-bar-striped progress-bar-success \" style=\"width:" + Percent + "%;\"></div>";
                     }
                      break;
    
            }
             return ReturnResult;
        }
    

    ผลลัพธ์

    หมายเหตุ : จากตัวอย่างข้างต้น เป็นเพียงการยกตัวอย่างเพื่อให้ผู้อ่านเข้าใจการประยุกต์ใช้งาน และการทำงานร่วมกับ Progress bar เพิ่มมากขึ้นเท่านั้น ซึ่งผู้อ่านสามารถดัดแปลง และมีวิธีการรวมถึงเทคนิคที่แตกต่างออกไปที่จะนำมาใช้ในการพัฒนาเพื่อแสดงผลข้อมูล ขึ้นกับอัลกอริธึมของแต่ละท่าน

              จากบทความนี้จะเห็นได้ว่า วิธีการดึงข้อมูลมาแสดงผลด้วย Progress bar แบบนี้ จะมีความยืดหยุ่นกว่าแบบที่มีการกำหนดค่าตายตัวในบทความก่อนหน้า อีกทั้งยังสามารถแสดงจำนวนแถบ Progress bar และสีได้ไม่จำกัด ขึ้นอยู่กับข้อมูล การกำหนดเงื่อนไขในการแสดงผล และความต้องการของผู้พัฒนาที่จะดึงข้อมูลมาแสดงผลนั่นเอง และผู้เขียนหวังเป็นอย่างยิ่งว่า บทความนี้ จะพอเป็นแนวทางในการนำไปใช้งานจริงให้กับทุกท่านได้นะคะ ขอบคุณค่ะ ^^

    แหล่งข้อมูลอ้างอิง :

    https://bestjquery.com/tutorial/progress-bar/demo78/

    https://www.jquery-az.com/boots/demo.php?ex=51.0_5