บทความนี้ผู้เขียนจะพูดถึงส่วนที่มีการทำงานในลักษณะคล้ายกับ Containner แต่ก่อนจะเริ่มเนื้อหาในส่วนนี้ สำหรับผู้ที่เริ่มต้นใหม่สามารถอ่านบทความ ตอนที่ 1 เพื่อความเข้าใจต่อเนื่องกันนะครับ ส่วนผู้ที่อ่านบทความก่อนหน้านี้ เรามาเริ่มกันเลยดีกว่าครับ
ก่อนที่ผู้เขียนจะไปพูดถึงส่วนของการเขียนโปรแกรมนั้น ผู้เขียนอยากอธิบายเพื่อทำความเข้าใจให้กับผู้อ่านได้เห็นภาพได้ชัดเจนเกี่ยวลักษณะการทำงานของ Containner แบบต่างๆให้ได้ทราบกัน โดยการทำงานของ Itextsharp นั้น เมื่อเราทำการสร้างเอกสารแล้ว เราไม่สามารถเขียนข้อความหรือใส่ข้อมูลต่างๆลงไปได้ในเอกสารโดยตรง แต่เราจะทำผ่านตัว Containner ครับ โดยตัว Containner ที่ Itextsharp ให้มาก็มีหลายรูปแบบให้เลือกใช้งานกัน วันนี้เราจะมาทราบกันว่ามีรูปแบบอะไรบ้างที่ช่วยให้เราทำงานได้ดีขึ้นครับ
รูปตัวอย่างแสดงการทำงานของ Containner
จากรูปตัวอย่างที่ผู้เขียนได้วาดไว้นั้น ผู้เขียนขออธิบายกรอบทั้งด้านซ้ายก่อนนะครับ โดยกรอบแต่ละสี จะเป็น Containner แต่ละที่ Itextsharp มีมาให้เราใช้งาน โดยกรอบสีดำนอกสุดนั้น ก็คือ Document หรือตัวเอกสารที่ได้กล่าวถึงในบทความก่อนหน้านี้ ซึ่งเป็น Containner ใหญ่สุดและเป็นตัวหลัก ใช้สำหรับบรรจุ Containner ตัวอื่นๆลงไปในเอกสาร ต่อมากรอบสีน้ำเงิน ก็คือ Paragraph เรียกง่ายๆว่าย่อหน้า ใน 1 Document นั้นเราสามารถบรรจุ Paragraph กี่อันก็ได้ตามที่ผู้ใช้ต้องการ โดยแต่ละ Paragraph จะเรียงต่อกันลงมาเป็นแนวตั้ง โดย Paragraph ล่าสุดจะอยู่ล่าสุดของเอกสารเสมอ ต่อกันด้วยกรอบสีแดง ก็คือ Phrase เรียกง่ายๆว่า รูปประโยค ใน 1 Paragraph สามารถมี Phrase ได้หลายอัน โดยต่อเรียงจากซ้ายไปขวา เราสามารถเขียนข้อมูลลงใน Phraph ได้ หรือเราใช้เป็น Containner สำหรับบรรจุ Chunk อีกชั้นได้ด้วย แต่ Phraph เหมาะสำหรับใช้เป็น containner มากกว่าใช้ใสข้อมูลโดยตรง เนื่องจากมีเงื่อนไขในการใส่ที่จำกัด และสุดท้ายของกรอบด้านซ้ายและเป็นตัวหลักในการเขียนข้อมูลคือ Chunk นั้นเอง Chunk เป็น Containner ที่มีหน้าที่ในการเก็บข้อมูลที่เราจะใส่ลงไปในเอกสารโดยเฉพาะ โดย Chunk จะต่อเรียงกันไปเลยๆจากซ้ายไปขวาเหมือน Phrase และไม่สามารถบรรจุ Containner อื่นลงไปได้อีก พออ่านมาถึงตรงนี้หลายท่านสงสัยว่า เรามาถึง Containner ตัวเล็กสุดแล้ว แล้วอีก 2 ตัวที่เหลือละ จริงๆผู้เขียนไม่ได้ลืมนะครับ แต่ผู้เขียนพยายามแยกการทำงานของ Containner เป็นชุดๆให้ผู้อ่านได้เข้าใจง่ายๆ เมื่อจบการอธิบายในกรอบด้านซ้ายของรูปตัวอย่างแล้ว เรามาเริ่ม กรอบทางด้านขวากันเลยดีกว่า เมื่อเราดูรูปกรอบด้านขวาจะพบว่ามี Containner บ้างตัวหายไป ทั้งที่มีการใช้งานทางด้านซ้าย ก็คือเจ้า Paragraph นั้นเอง เพราะผู้เขียนคิดว่าการทำงานของ Paragraph นั้นจะซ้ำซ้อนกับ PdfPCell นั้นเอง แต่ก่อนจะพูดถึง PdfPCell สิ่งที่ลืมไปไม่ได้เลยคือ PdfPtable นั้นเอง สำหรับผู้พัฒนาโปรแกรม คงเข้าใจได้ง่ายๆว่า ถ้าเราจะสร้างCell เราจะขาด Table ไปไม่ได้ เพราะ Cell เป็นส่วนนึงของ Tableนั้นเอง โดย PdfpTable จะทำหน้าที่ในการบรรจุ Containner PdfPCell ไว้นั้นเอง เมื่อเราทำการใส่ PdfPCell ลงใน PdfPTable แล้ว PdfPCell จะเรียงต่อกันจากซ้ายไปขวา เรื่อยๆ แล้วหลายคนสงสัย แล้วไม่มี PdfPRow ให้ใช้งานหรอ มีครับแต่ไม่ค่อยได้รับความนิยมในการใช้งานมากนัก เพราะตัว PdfPTable นั้นสามารถเพิ่ม PdfPCell ได้โดยตรงไม่ต้องเพิ่ม PdfPRow แต่อย่างใด ผู้เขียนจึงขอตัดออกไปก่อน แต่จะมีตัวอย่างการใช้งานให้ดูตอนท้ายครับ แล้วถามว่าเราสามารถเอา PdfPTable ไปใส่ใน Paragraph ได้ไหม ได้ครับ เราสามารถเอา PdfPTable ใน Paragraph และเช่นเดียวกันเราสามารถเอา Paragraph ใส่ใน PdfPTable รู้สึกผู้เขียนจะร่ายยาวไปแล้ว คนอ่านคงเบื่อ เรามาเข้าสู่ช่วงของการเขียนโปรแกรมกันเลยดีกว่า โดยเริ่มจากตัว Containner ตัวเล็กสุดคือ Chunk
Chunk chk1 = new Chunk("Howdy",fnt);//1 Chunk chk2 = new Chunk();//2 chk2.Append("Howdy"); chk2.Font = fnt; Phrase P = new Phrase(new Chunk("Howdy", fnt));//3
จากตัวอย่างด้านบนจะเป็นรูปแบบการใช้งาน Chunk ในรูปแบบต่างๆกันขึ้นอยู่กับความเหมาะสมหรือความถนัดของผู้ใช้งาน แบบที่ 1 จะเป็นการประกาศใช้งานพร้อมทั้งกำหนดค่าข้อมูลและรูปแบบของ font ลงไปในขั้นตอนเดียว ส่วนแบบที่ 2 จะแตกต่างตรงที่ประกาศการใช้งาน Chunk ขึ้นมาก่อนแล้วค่อยไปกำหนดค่าข้อมูลและรูปแบบ Font ภายหลัง หรือแบบที่ 3 เป็นการสร้าง Chunk ลงไปใน Containner ตัวอื่นโดยตรง แบบนี้ไม่สามารถแก้ไขข้อมูลได้แล้วครับ Containner ตัวต่อมาคือ Phrase มาดูตัวอย่าง Code กัน
Chunk ck1 = new Chunk("Howdy ",fnt); Chunk ck2 = new Chunk("You",fnt); Phrase P1 = new Phrase(new Chunk("Howdy You", fnt));//1 Phrase P2 = new Phrase("Howdy You",fnt);//2 Phrase P3 = new Phrase();//3 P3.Add("Howdy "); P3.Add("You"); Phrase P4 = new Phrase();//4 P4.Add(ck1); P4.Add(ck2); Paragraph PR1 = new Paragraph(new Phrase("Howdy You",fnt));//5
จากตัวอย่างทั้งหมด ผลลัพธ์ที่ได้คือ Howdy You เหมือนกันหมดครับต่างกันแค่วิธีการเขียนเท่านั้นเอง ในตัวอย่างที่ 1 เป็นการใช้งานแบบประกาศ Phrase ขึ้นมาพร้อมกับสร้าง Chunk ขึ้นมาพร้อมกำหนดค่าข้อมูลเพิ่มมาด้วยในชุดคำสั่งเดียว ซึ่งในตัวอย่างที่ 2 มีการเขียนเหมือนกันต่างตรงที่ เขียนข้อมูลและรูปแบบตรงๆ ไม่ผ่านทาง Chunk นั้นเอง ส่วนตัวอย่างที่ 3 และ 4 จะมีการประกาศใช้งาน Phrase ในชื่อ P3 และ P4 ต่างกันตรงที่ P3 จะทำการเพิ่มข้อมูลตรงในรูปแบบของ String แต่ P4 จะนำ Chunk ที่ได้สร้างไว้ก่อนมาใช้งาน ถ้าสังเกตุดีๆจะพบว่า แบบตัวอย่างที่ 3 นั้นไม่สามารถกำหนดรูปแบบของข้อความได้ ต่างจากตัวอย่างที่ 4 ที่มีการกำหนดรูปแบบมาแล้วใน Chunk ซึ่งแบบนี้จะทำงานได้ง่ายกว่าและยืดหยุ่นมากว่าด้วยครับ และสุดท้ายตัวอย่างที่ 5 เป็นการสร้าง Phrase ซ้อนอยู่ในการประกาศ Paragarph นั้นเอง ทำให้เราไม่สามารถแก้ไขข้อมูลใน Phraseได้แล้วครับ Containner ตัวต่อมาที่จะพูดถึงคือ Paragarph มาดูตัวอย่าง Code กัน
Paragraph PR1 = new Paragraph(new Phrase("Howdy You",fnt));//1 Paragraph PR2 = new Paragraph(new Phrase(new Chunk("Howdy You", fnt)));//2 Paragraph PR3 = new Paragraph();//3 PR3.Add("Howdy You"); Paragraph PR4 = new Paragraph();//4 PR4.Add(new Chunk("Howdy You", fnt)); Paragraph PR5 = new Paragraph();//5 PR5.Add(new Phrase(new Chunk("Howdy You", fnt))); Paragraph PR6 = new Paragraph();//6 PR6.Add(P1); Paragraph PR7 = new Paragraph();//7 PR7.Add(ck1); PR7.Add(ck2); pdfDoc.Add(new Paragraph("Howdy You"));//8
จากตัวอย่างรูปแบบที่ 1 และ 2 เป็นการเขียนในลักษณะที่คล้ายกันคือทำการประกาศ Paragraph พร้อมทั้งประกาศ Containner ตัวที่เล็กกว่าใส่ลงไปด้วยและทำการเขียนข้อมูล ต่างกันเพียง แบบที่ 2 จะประกาศซ้อนลงไปอีกชั้นนึงในส่วนของ Chunk นั้นเอง ส่วนตัวอย่างแบบที่ 4 5 6 และ 7 ใช้การประกาศ Containner ที่เหมือนกัน ต่างกันตรงการเพิ่มข้อมูลลง Paragraph นั้นๆ และสุดท้ายตัวอย่างที่ 8 คือการประกาศ Paragraph ลงไปใน Document เลยนั้นเอง แล้วเราก็มาถึง 2 ตัวสุดท้ายของบทความนี้แล้วครับ นั้นก็คือ PdfPtable และ PdfPcell นั้นเอง นั้นส่วนของ 2 ตัวนี้จะยกตัวอย่างแบบพื้นฐานให้ดูก่อนนะครับ จะไม่ได้ดูรายละเอียดเยอะมาก เดี๋ยวจะยาวเกินไปครับ เรามาดูตัวอย่างกันเลยดีกว่า
//-------------- 1 -------------// PdfPTable PdfTable = new PdfPTable(4); float[] tbwidths = { 10f, 10f, 10f, 10f }; PdfTable.SetWidths(tbwidths); //-------------- 2 -------------// PdfPCell PdfCell = new PdfPCell(new Phrase("Howdy You",fnt)); PdfPCell PdfCell2 = new PdfPCell(new Phrase(new Chunk("Howdy You", fnt))); PdfPCell PdfCell3 = new PdfPCell(); PdfCell3.AddElement(P1); //-------------- 3 -------------// PdfTable.AddCell(PdfCell); PdfTable.AddCell(PdfCell2); PdfTable.AddCell(PdfCell3); PdfTable.AddCell(new PdfPCell(new Phrase("Howdy You",fnt)));
จากตัวอย่างผู้เขียนได้แบ่งcode ออกเป็น 3 ส่วนดังนี้ ส่วนที่ 1 จะเป็นส่วนของการประกาศและสร้าง Table ขึ้นมาครับ โดยผู้เขียนได้สร้าง Table ชื่อ PdfTable ซึ่ง Table นี้มีขนาด 4 Colunm บบรทัดต่อมาจะเป็นส่วนของการจัดความกว้างของ Colunm ส่วนนี้ต้องระวังนิดนึงคือ จำนวนต้องมีเท่ากับจำนวน Colunm ของ Table นะครับ ส่วนเรื่องขนาดความกว้าง อันนี้แล้วแต่ตามความเหมาะสมในการใช้งาน ตัวโปรแกรม Itextsharp ช่วยเราเรื่องการขยายขนาดให้พอดีครับ อันนี้ต้องลองเล่นๆดูจะเข้าใจมากขึ้น บรรทัดต่อมาเป็นการนำค่าความกว้างที่ตั้งไว้กำหนดให้ Table ของเรา ก็จะจบการสร้างtableแบบพื้นฐานแล้ว เรามาต่อกันส่วนที่ 2 ในส่วนนี้จะเป็นส่วนของการประกาศและสร้าง PdfPCell ในรูปแบบต่างๆ ซึ่งรูปแบบจะคล้ายๆกับการสร้าง containner ตัวอื่นๆที่ผ่านมา และส่วนที่ 3 เป็นส่วนที่นำเอาส่วนที่ 2 หรือก็คือ PdfPCell ของเรานั้นเอง ใส่ลงไปยัง PdfPTable ที่ได้สร้างไว้ในส่วนที่ 1 แค่นี้ก็ถือว่าเสร็จสิ้นการสร้าง Table แล้วครับ แล้วลืมไม่ได้เลยคือตัวอย่างการใช้งาน PdfPRow ที่ได้สัญญาเอาไว้ในตอนแรก
//-------------- 1 -------------// PdfPTable PdfTable = new PdfPTable(4); float[] tbwidths = { 10f, 10f, 10f, 10f }; PdfTable.SetWidths(tbwidths); //-------------- 2 -------------// PdfPCell PdfCell = new PdfPCell(new Phrase("Howdy You",fnt)); PdfPCell[] cells = new PdfPCell[] { new PdfPCell(), new PdfPCell(), new PdfPCell(), new PdfPCell()}; cells[0].AddElement(new Phrase("Howdy You", fnt)); cells[1].AddElement(new Phrase(new Chunk("Howdy You", fnt))); cells[2].AddElement(PR1); cells[3] = PdfCell; //-------------- 3 -------------// PdfPRow row = new PdfPRow(cells); PdfTable.Rows.Add(row);
สุดท้ายนี้ขอขอบคุณผู้ที่สนใจอ่านบทความของผู้เขียนครับ หลังจากนี้มีเวลาว่างจะมาเขียนต่อในส่วนอื่นๆให้ได้อ่านกันต่อไปครับ และสำหรับเนื้อหาที่เขียนในบทความมาจากประสบการณ์จากผู้เขียนเอง ถ้ามีส่วนไหนผิดพลาด ตกหล่น ก็ขออภัยไว้นะที่นี้ด้วยครับ