--- layout: post type: handbook title: "PDF Styling" date: 2013-12-19 tags: coding --- จะมี style คร่าวๆ ให้ได้จัดการปรับแต่งกันเอง (โดยเฉพาะตำแหน่งการวาง ชิดซ้าย กลาง ชิดขวา) ใน core.views.pdfs ซึ่งจริงๆแล้วก็จะแบ่งมาตรฐานเป็น 2 ส่วน คือ * `Paragraph` -- กำหนดด้วย `ParagraphStyle` * `Table` -- กำหนด style ด้วย `style_tab` (แต่ต้องใส่เองทั้งหมด) ## Paragraph ในส่วนนี้จะเป็นการกำหนด style คร่าวๆ เพื่อให้เป็นแนวทางหลักในการใช้งานทั้งหมด โดยมีทั้งหมดดังนี้ 1. `style_base` - อันนี้เอาไว้เป็น parent style เฉยๆครับ เพราะมีกำหนดแค่รูปแบบตัวอักษรเป็น TH Sarabun 1. `style_h1` - ขนาด font 18 ตัวหนา พร้อมมี space บนล่างตามเหมาะสม 1. `style_h1c` - อันนี้คือ `h1` แต่ตั้ง align เป็น center ครับ 1. `style_h2` - ขนาด font 16 ตัวหนา พร้อมมี space บนล่างตามเหมาะสม 1. `style_h2c` - อันนี้คือ `h2` แต่ตั้ง align เป็น center ครับ 1. `style_h3` - ขนาด font 14 ตัวหนา พร้อมมี space บนล่างตามเหมาะสม 1. `style_h3c` - อันนี้คือ `h2` แต่ตั้ง align เป็น center ครับ 1. `style_normal` - ขนาด font 14 ไม่มี space บนล่าง ไม่มีย่อหน้า 1. `style_normal_indent` - เหมือน `style_normal` แต่มีย่อหน้าของบรรทัดแรกเข้าไป 4 space ครับ 1. `style_footnote` - อันนี้สำหรับอธิบายใต้ตารางครับ ตัวเล็กๆ 12 ไม่มี space บนล่าง ไม่มีย่อหน้า หรือจะเป็น code ก็ตามด้านล่างนี้ style_base = ParagraphStyle('normal', parent=style_base_sample, fontName='TH Sarabun New') style_h1 = ParagraphStyle('h1', parent=style_base, fontName='TH Sarabun New Bold', fontSize=18, leading=21, spaceBefore=7, spaceAfter=8,) style_h1c = ParagraphStyle('h1c', parent=style_h1, alignment=TA_CENTER,) style_h2 = ParagraphStyle('h2', parent=style_base, fontName='TH Sarabun New Bold', fontSize=16, leading=19, spaceBefore=7, spaceAfter=8,) style_h2c = ParagraphStyle('h1c', parent=style_h2, alignment=TA_CENTER,) style_h3 = ParagraphStyle('h2', parent=style_base, fontName='TH Sarabun New Bold', fontSize=14, leading=17, spaceBefore=7, spaceAfter=8,) style_h3c = ParagraphStyle('h1c', parent=style_h3, alignment=TA_CENTER,) style_normal = ParagraphStyle('normal', parent=style_base, fontSize=14, leading=17,) style_normal_indent = ParagraphStyle('normal', parent=style_normal, firstLineIndent=16) style_footnote = ParagraphStyle('footnote', parent=style_base, fontSize=12, leading=15,) การใช้งานจะสามารถ import ได้ประมาณนี้ from core.views.pdfs import style_h1, style_h1c, style_normal style พวกนี้อาจจะตอบคำถามไม่ได้หมด เช่น ตัวชิดขอบซ้าย ขอบขวาจะทำอย่างไร แนะนำให้ทำตามนี้เพื่อให้ code ดูสะอาดและจัดการง่ายที่สุดครับ เช่น กรณีเราต้องการส่วนที่พิมวันที่ซึ่งจะมีขนาดตามปกติ (`style_normal`) แต่มันจะต้องชิดขอบขวา ก็จะสามารถทำได้โดยสร้าง style ของตัวเองเป็น style_normal_right = ParagraphStyle('nr', parent=style_normal, alignment=TA_RIGHT,) ตอนนี้เราก็จะได้ style ที่ชิดขวามาแล้วโดยที่เราไม่ได้กำหนดรูปแบบตัวอักษรเองเลย เพียงแค่กำหนดว่าให้มันชิดฝั่งไหนก็พอตรง `alignment=TA_RIGHT` ส่วนในเรื่องของย่อหน้านั้นจะมี 2 เรื่องที่ต้องรู้คือ 1. `firstLineIndent` อันนี้จะคือ จะให้ย่อหน้าเท่าไหร่สำหรับบรรทัดแรก แล้วบรรทัดอื่นก็จะกลับมาชิดซ้ายสุดเหมือนเดิม 1. `leftIndent` จะเป็นการเลื่อนตำแหน่งขอบซ้ายทั้งย่อหน้า เหมือนอารมณ์ใช้กับ list ที่เป็นข้อๆ มันจะไม่ล้นไปซ้ายสุดขอบกระดาษ แต่เป็นการกำหนดว่า เลื่อนขอบซ้ายทั้ง `Paragraph` 1. หน่วยของค่าที่ใช้สำหรับ 2 ตัวนี้ ก็ไม่แน่ใจเหมือนกันว่า คืออะไรครับ แต่ 4 คือ เท่ากับ 1 ตัวอักษร หรือถ้าต้องการ 4 space ก็จะต้องใช้ `firstLineIndent=16` เป็นต้น ทั้งสองอันนี้สามารถใช้ร่วมกันได้ครับ ไม่มีปัญหาอะไร ส่วนหนึ่งที่ผมคิดว่า น่าจะมีปัญหาคือ ความสูงระหว่าง `Paragraph` หรือ `spaceBefore` และ `spaceAfter` ทาง style ข้างต้นจะมีการกำหนดเพียงแค่ส่วนของ `style_h1`, `style_h1c`, `style_h2`, `style_h2c`, `style_h3`, `style_h3c` แต่ในส่วนของ `style_normal` จะไม่ได้กำหนดไว้ ดังนั้นจะสามารถเลือกได้เองว่าจะทำ style ใหม่เพื่อเพิ่มในส่วนนี้ หรือว่าจะใช้ Spacer ก็ได้ ### Spacer เป็นแค่ตัวว่างเปล่าไว้กำหนดความสูง from core.views.pdfs import Spacer เวลาใช้ก็ lst.append(Spacer(1, 0.2*inch)) ก็จะได้พื้นที่ว่างระหว่างตัวบนกับตัวล่างมาแล้ว 1/5 ของ 1 นิ้ว ## Table ส่วนของ Table นั้น ไม่สามารถตั้งมาตรฐานได้อย่างชัดเจน การกำหนดมาตรฐานคร่าวๆ ของตารางก็จะเป็น (1) การบังคับความกว้างของตารางและ (2) style ก็จะมีการกำหนดขนาดแบบ font, สี ความกว้างของตาราง เท่าที่ดูจะต้องมีการทำกระดาษแบบ landscape ด้วย แต่ไว้สรุปในเวลาต่อไป ตอนนี้ก็เป็นมาตรฐานแนวตั้งไปก่อน 1. ตารางกว้างได้สูงสุด 6.8" แนวตั้ง ส่วนแนวนอนยังไม่ได้รองรับในขณะนี้ 1. ตารางมีขนาดได้ตั้งแต่ 5.8" - 6.8" เท่านั้น เว้นแต่จะได้รับการยอมรับแล้ว 1. รวมทั้งส่วนของลายเซ็นก็เช่นกัน จะต้องเป็น table กว้างไม่ <= 6.8" 1. ในกรณีที่ในรายงานมีหลายตารางในหน้าเดียวกัน ความกว้างของรายงานจะต้องมีความกว้างเท่ากันทั้งหมด แม้ว่าจะมีจำนวน column ไม่เท่ากัน หรืออย่างไรก็ตามครับ ก็ปรับให้มันเท่ากันซะ #### การกำหนดขนาดของ Table จากเดิมที่รูปแบบจะเป็น t = Table(data, style=xxxxxxxxx) ก็จะมีตัวแปรเพิ่มขึ้นมาเป็น t = Table(data, colWidths=[0.25*inch, 1.25*inch, 2.0*inch, 1.25*inch, 1.25*inch, 1.0*inch], style=xxxxxxxxx ) หรือจะใช้เป็น t = Table(data, colWidths=[0.25*inch, 1.25*inch, 2.0*inch, 1.25*inch, 1.25*inch, 1.0*inch] ) t.setStyle(TableStyle(xxxxxx)) จะสังเกตเห็นได้ว่า `colWidths` มีการกำหนดตัวเลขชัดเจน เป็นความกว้างของตารางทั้งหมด (กำหนดด้วยบรรทัดที่มี column มากที่สุด ส่วนเรื่อง SPAN มันจัดการให้ตรงกับความกว้างเองครับ) สิ่งที่อธิบายได้คือ ความกว้างของตารางทั้งหมดคือ 0.25 + 1.25 + 2 + 1.25 + 1.25 + 1 = 7 แสดงว่า ตารางนี้มีความกว้างเกินที่กำหนดไว้ (จริงๆแล้วมันคือ กว้างเกินส่วนของ Paragraph จากซ้ายถึงขวาด้วย มันจะไม่สวยครับ) จะต้องแก้ไขให้ได้ 6.8 หรือน้อยกว่า เช่น 0.25 + 1.25 + 2 + 1.15 + 1.15 + 1 = 6.8 ให้ได้เท่ากับ 6.8 #### การกำหนด style ส่วนนี้จะขึ้นกับตัวแปร style_tab from core.views.pdfs import style_tab ส่วนการใช้งานแทนที่จะเขียนลงไปชัดเจนในส่วนของ fontface, fontsize ก็จะกลายเป็น number_table_style = [ ('FONTNAME', (0,0), (-1,-1), style_tab['font']), ('INNERGRID', (0,0), (-1,-1), 0.5 , style_tab['header_bg']), ('FONTSIZE', (0, 0), (-1, -1), 13), ('BOTTOMPADDING', (0, 0), (-1, -1), 4), ('FONTNAME', (0,0), (8,2), style_tab['header_font']), ('ALIGN',(1,4),(-1,-1),'LEFT'), ('ALIGN',(2,4),(-1,-1),'RIGHT'), ('BACKGROUND',(0,0),(8,2), style_tab['header_bg']), ('SPAN',(0,0),(0,2)), ('ALIGN',(0,0),(0,2),'CENTER'), ('VALIGN',(0,0),(0,2),'MIDDLE'), ('SPAN',(1,0),(1,2)), ('ALIGN',(1,0),(1,2),'CENTER'), ('VALIGN',(1,0),(1,2),'MIDDLE'), ('SPAN',(-7,0),(-2,0)), ('ALIGN',(-7,0),(-2,0),'CENTER'), ('SPAN',(8,0),(8,2)), ('ALIGN',(8,0),(8,2),'CENTER'), ('VALIGN',(8,0),(8,2),'MIDDLE'), ('SPAN',(2,1),(4,1)), ('ALIGN',(2,1),(4,1),'CENTER'), ('SPAN',(5,1),(7,1)), ('ALIGN',(5,1),(7,1),'CENTER'), ('SPAN',(0,3),(8,3)), ('SPAN',(0,-1,),(1,-1)), ('FONTNAME', (0,-2), (8,-1), style_tab['header_font']), ('LINEABOVE', (0,0), (-1,-1), 0.5 , style_tab['header_bg']), ('LINELEFT', (0,0), (-1,-1), 0.5 , style_tab['header_bg']), ('GRID', (0,0), (-1,-1), 0.5 , style_tab['grid_color']), ] จะสังเกตได้ว่า `style_tab` จะไปทดแทนการกำหนดสีพื้น, สี border, fontface, fontsize ทั้งหมดจากเดิมที่จะใช้ `colors.grey`, 'TH Sarabun New' เป็นต้น สิ่งที่สามารถเรียกได้จาก `style_tab` คือ * `style_tab['font']` -- คือ font ปกติในตาราง * `style_tab['header_font']` -- คือ font ตัวหนา * `style_tab['header_bg']` -- คือ สีพื้นของหัวตาราง (สีเทา) * `style_tab['fontsize']` -- คือ ขนาด font * `style_tab['grid_color']` -- คือ สีของ border ของตาราง