วิธีสร้าง PDF จากเว็บแอปพลิเคชันของคุณ
เผยแพร่แล้ว: 2022-03-10เว็บแอปพลิเคชั่นจำนวนมากมีข้อกำหนดในการให้ผู้ใช้สามารถดาวน์โหลดบางสิ่งในรูปแบบ PDF ในกรณีของแอปพลิเคชัน (เช่น ร้านค้าอีคอมเมิร์ซ) จะต้องสร้าง PDF เหล่านั้นโดยใช้ข้อมูลแบบไดนามิก และพร้อมให้ผู้ใช้ใช้งานได้ทันที
ในบทความนี้ ฉันจะสำรวจวิธีการต่างๆ ที่เราสามารถสร้าง PDF ได้โดยตรงจากเว็บแอปพลิเคชันได้ทันที ไม่ใช่รายการเครื่องมือที่ครอบคลุม แต่ฉันตั้งใจที่จะสาธิตแนวทางต่างๆ แทน หากคุณมีเครื่องมือโปรดหรือประสบการณ์ส่วนตัวที่จะแบ่งปัน โปรดเพิ่มลงในความคิดเห็นด้านล่าง
เริ่มต้นด้วย HTML และ CSS
เว็บแอปพลิเคชันของเรามีแนวโน้มที่จะสร้างเอกสาร HTML โดยใช้ข้อมูลที่จะเพิ่มลงใน PDF ของเราแล้ว ในกรณีของใบแจ้งหนี้ ผู้ใช้อาจสามารถดูข้อมูลออนไลน์ได้ จากนั้นคลิกเพื่อดาวน์โหลดไฟล์ PDF เพื่อเป็นหลักฐาน คุณอาจกำลังสร้างใบบรรจุภัณฑ์ อีกครั้งที่ข้อมูลถูกเก็บไว้ในระบบแล้ว คุณต้องการจัดรูปแบบในลักษณะที่ดีสำหรับการดาวน์โหลดและพิมพ์ ดังนั้น จุดเริ่มต้นที่ดีคือการพิจารณาว่าสามารถใช้ HTML และ CSS นั้นเพื่อสร้างเวอร์ชัน PDF ได้หรือไม่
CSS มีข้อกำหนดที่เกี่ยวข้องกับ CSS สำหรับการพิมพ์ และนี่คือโมดูล Paged Media ฉันมีภาพรวมของข้อกำหนดนี้ในบทความ "การออกแบบสำหรับการพิมพ์ด้วย CSS" และ CSS ถูกใช้โดยผู้จัดพิมพ์หนังสือหลายรายสำหรับผลงานพิมพ์ทั้งหมด ดังนั้น เนื่องจาก CSS เองมีข้อกำหนดสำหรับสื่อสิ่งพิมพ์ เราจึงควรใช้มันได้หรือไม่
วิธีที่ง่ายที่สุดที่ผู้ใช้สามารถสร้าง PDF ได้คือผ่านเบราว์เซอร์ เมื่อเลือกพิมพ์เป็น PDF แทนที่จะเป็นเครื่องพิมพ์ ระบบจะสร้าง PDF น่าเศร้าที่ PDF นี้มักจะไม่น่าพอใจเลย! ในการเริ่มต้น จะมีส่วนหัวและส่วนท้ายซึ่งจะถูกเพิ่มโดยอัตโนมัติเมื่อคุณพิมพ์บางอย่างจากหน้าเว็บ นอกจากนี้ยังจะจัดรูปแบบตามสไตล์ชีตการพิมพ์ของคุณด้วย สมมติว่าคุณมี
ปัญหาที่เราพบในที่นี้คือการสนับสนุนที่ไม่ดีของข้อกำหนดการแตกแฟรกเมนต์ในเบราว์เซอร์ ซึ่งอาจหมายความว่าเนื้อหาของหน้าของคุณแตกในลักษณะที่ผิดปกติ การสนับสนุนการกระจายตัวเป็นหย่อมๆ ตามที่ฉันค้นพบเมื่อฉันค้นคว้าบทความ "Breaking Boxes With CSS Fragmentation" ซึ่งหมายความว่าคุณอาจไม่สามารถป้องกันการแบ่งเนื้อหาที่ไม่เหมาะสมได้ โดยส่วนหัวจะเหลือเป็นรายการสุดท้ายบนหน้า และอื่นๆ
นอกจากนี้ เราไม่สามารถควบคุมเนื้อหาในกล่องระยะขอบของหน้าได้ เช่น การเพิ่มส่วนหัวที่เราเลือกในแต่ละหน้าหรือการกำหนดหมายเลขหน้าเพื่อแสดงจำนวนหน้าในใบแจ้งหนี้ที่ซับซ้อน สิ่งเหล่านี้เป็นส่วนหนึ่งของข้อกำหนด Paged Media แต่ยังไม่มีการใช้งานในเบราว์เซอร์ใดๆ
บทความของฉัน “A Guide To The State Of Print Stylesheets In 2018” ยังคงถูกต้องในแง่ของประเภทของการสนับสนุนที่เบราว์เซอร์มีสำหรับการพิมพ์โดยตรงจากเบราว์เซอร์โดยใช้สไตล์ชีตการพิมพ์
การพิมพ์โดยใช้เครื่องมือแสดงผลของเบราว์เซอร์
มีวิธีพิมพ์เป็น PDF โดยใช้กลไกแสดงผลของเบราว์เซอร์ โดยไม่ต้องผ่านเมนูพิมพ์ในเบราว์เซอร์ และลงท้ายด้วยส่วนหัวและส่วนท้ายราวกับว่าคุณได้พิมพ์เอกสาร ตัวเลือกที่ได้รับความนิยมมากที่สุดในการตอบกลับทวีตของฉันคือ wkhtmltopdf และการพิมพ์โดยใช้ Chrome และ Puppeteer แบบไม่มีหัว
wkhtmltopdf
วิธีแก้ปัญหาที่ถูกกล่าวถึงหลายครั้งบน Twitter คือเครื่องมือบรรทัดคำสั่งที่เรียกว่า wkhtmltopdf เครื่องมือนี้ใช้ไฟล์ HTML หรือหลายไฟล์ พร้อมกับสไตล์ชีตและแปลงเป็น PDF ทำได้โดยใช้เอ็นจินการเรนเดอร์ WebKit
เราใช้ wkhtmltopdf มันไม่สมบูรณ์แบบ แม้ว่านั่นอาจเป็นข้อผิดพลาดของผู้ใช้ แต่ก็ดีพอสำหรับแอปพลิเคชันที่ใช้งานจริงได้ง่าย
– Paul Cardno (@pcardno) วันที่ 15 กุมภาพันธ์ 2019
โดยพื้นฐานแล้ว เครื่องมือนี้ทำงานเหมือนกับการพิมพ์จากเบราว์เซอร์ อย่างไรก็ตาม คุณจะไม่ได้รับส่วนหัวและส่วนท้ายที่เพิ่มโดยอัตโนมัติ ในด้านบวกนี้ หากคุณมีสไตล์ชีตการพิมพ์ที่ใช้งานได้สำหรับเนื้อหาของคุณ ก็ควรส่งออกเป็น PDF อย่างสวยงามโดยใช้เครื่องมือนี้ ดังนั้นเลย์เอาต์ที่เรียบง่ายอาจพิมพ์ออกมาได้อย่างสวยงาม
อย่างไรก็ตาม ขออภัย คุณจะยังคงประสบปัญหาเดียวกันกับเมื่อพิมพ์โดยตรงจากเว็บเบราว์เซอร์ ในแง่ของการขาดการสนับสนุนสำหรับข้อมูลจำเพาะ Paged Media และคุณสมบัติการแตกแฟรกเมนต์ เนื่องจากคุณยังคงพิมพ์โดยใช้กลไกการแสดงผลของเบราว์เซอร์ มีแฟล็กบางอย่างที่คุณสามารถส่งผ่านไปยัง wkhtmltopdf เพื่อเพิ่มกลับคุณสมบัติที่ขาดหายไปซึ่งคุณจะมีโดยค่าเริ่มต้นโดยใช้ข้อกำหนด Paged Media อย่างไรก็ตาม สิ่งนี้ต้องการการทำงานพิเศษนอกเหนือจากการเขียน HTML และ CSS ที่ดี
หัวขาด Chrome
ความเป็นไปได้ที่น่าสนใจอีกประการหนึ่งคือการใช้ Headless Chrome และ Puppeteer เพื่อพิมพ์เป็น PDF
เชิดหุ่น มันวิเศษมากสำหรับสิ่งนี้
– อเล็กซ์รัสเซล (@slightlylate) วันที่ 15 กุมภาพันธ์ 2019
อย่างไรก็ตาม คุณถูกจำกัดด้วยการสนับสนุนเบราว์เซอร์สำหรับ Paged Media และการแตกแฟรกเมนต์อีกครั้ง มีบางตัวเลือกที่สามารถส่งผ่านไปยัง page.pdf()
ได้ เช่นเดียวกับ wkhtmltopdf สิ่งเหล่านี้จะเพิ่มฟังก์ชันการทำงานบางอย่างที่อาจเป็นไปได้จาก CSS หากมีการสนับสนุนเบราว์เซอร์
อาจเป็นไปได้ว่าหนึ่งในโซลูชันเหล่านี้จะทำทุกอย่างที่คุณต้องการ อย่างไรก็ตาม หากคุณพบว่าคุณกำลังต่อสู้ในการต่อสู้ เป็นไปได้ว่าคุณกำลังบรรลุขีดจำกัดของสิ่งที่เป็นไปได้ด้วยเอ็นจิ้นการเรนเดอร์เบราว์เซอร์ปัจจุบัน และ คงต้องหาทางแก้ไขให้ดีขึ้น
JavaScript Polyfills สำหรับสื่อที่มีเพจ
มีความพยายามไม่กี่ครั้งในการทำซ้ำข้อกำหนด Paged Media ในเบราว์เซอร์โดยใช้ JavaScript โดยพื้นฐานแล้วคือการสร้าง Paged Media Polyfill สิ่งนี้สามารถให้การสนับสนุน Paged Media แก่คุณเมื่อใช้ Puppeteer ดูที่ paged.js และ Vivliostyle
ใช่. สำหรับเอกสารทั่วไป เช่น ใบรับรองหลักสูตร เราสามารถใช้ Chrome ซึ่งรองรับ @ เพจเพียงเล็กน้อย สำหรับอย่างอื่น เราใช้ PrinceXML หรือ polyfill ของ paged.js ใน Chrome นี่คือแนวคิดในการพิสูจน์ WIP โดยใช้ paged.js สำหรับหนังสือ: https://t.co/AZ9fO94PT2
– Electric Book Works (@electricbook) วันที่ 15 กุมภาพันธ์ 2019
การใช้ตัวแทนผู้ใช้การพิมพ์
หากคุณต้องการใช้โซลูชัน HTML และ CSS ต่อไป คุณต้องมองหา User Agent (UA) ที่ออกแบบมาสำหรับการพิมพ์จาก HTML และ CSS ซึ่งมี API สำหรับสร้าง PDF จากไฟล์ของคุณ User Agents เหล่านี้ใช้ข้อกำหนด Paged Media และมีการสนับสนุนที่ดีกว่าสำหรับคุณสมบัติ CSS Fragmentation สิ่งนี้จะช่วยให้คุณควบคุมผลลัพธ์ได้ดียิ่งขึ้น ตัวเลือกชั้นนำ ได้แก่ :
- เจ้าชาย
- บ้านเสาอากาศ
- PDFReactor
UA แบบพิมพ์จะจัดรูปแบบเอกสารโดยใช้ CSS เช่นเดียวกับที่เว็บเบราว์เซอร์ทำ เช่นเดียวกับการรองรับเบราว์เซอร์สำหรับ CSS คุณต้องตรวจสอบเอกสารประกอบของ UA เหล่านี้เพื่อดูว่ารองรับอะไร ตัวอย่างเช่น Prince (ซึ่งฉันคุ้นเคยมากที่สุด) รองรับ Flexbox แต่ไม่รองรับ CSS Grid Layout ในขณะที่เขียน เมื่อส่งหน้าของคุณไปยังเครื่องมือที่คุณใช้ โดยทั่วไปแล้วจะเป็นด้วยสไตล์ชีตเฉพาะสำหรับการพิมพ์ เช่นเดียวกับสไตล์ชีตการพิมพ์ทั่วไป CSS ที่คุณใช้บนไซต์ของคุณจะไม่เหมาะสมกับเวอร์ชัน PDF ทั้งหมด
การสร้างสไตล์ชีตสำหรับเครื่องมือเหล่านี้มีความคล้ายคลึงกับการสร้างสไตล์ชีตการพิมพ์ทั่วไป การตัดสินใจเกี่ยวกับสิ่งที่จะแสดงหรือซ่อน อาจใช้ขนาดฟอนต์หรือสีที่ต่างกัน จากนั้น คุณจะสามารถใช้ประโยชน์จากคุณสมบัติต่างๆ ในข้อกำหนด Paged Media เพิ่มเชิงอรรถ หมายเลขหน้า และอื่นๆ
ในแง่ของการใช้เครื่องมือเหล่านี้จากเว็บแอปพลิเคชันของคุณ คุณจะต้องติดตั้งบนเซิร์ฟเวอร์ของคุณ (แน่นอนว่าต้องซื้อใบอนุญาตในการทำเช่นนั้น) ปัญหาหลักของเครื่องมือเหล่านี้คือมีราคาแพง ที่กล่าวว่าเนื่องจากความสะดวกในการสร้างเอกสารที่พิมพ์กับพวกเขา พวกเขาอาจจ่ายเงินสำหรับตัวเองโดยประหยัดเวลาของนักพัฒนา
เป็นไปได้ที่จะใช้ Prince ผ่าน API แบบจ่ายต่อเอกสาร ผ่านบริการที่เรียกว่า DocRaptor นี่จะเป็นสถานที่ที่ดีสำหรับการเริ่มต้นแอปพลิเคชันจำนวนมาก ราวกับว่าจะคุ้มค่ากว่าในการโฮสต์ของคุณเอง ต้นทุนการพัฒนาของการเปลี่ยนจะน้อยที่สุด
ทางเลือกฟรีซึ่งไม่ครอบคลุมเท่าเครื่องมือด้านบนแต่อาจบรรลุผลลัพธ์ที่คุณต้องการคือ WeasyPrint มันไม่ได้ใช้งาน Paged Media ทั้งหมดอย่างสมบูรณ์ อย่างไรก็ตาม มันใช้งานได้มากกว่ากลไกของเบราว์เซอร์ แน่นอนหนึ่งที่ต้องลอง!
เครื่องมืออื่นๆ ที่อ้างว่าสนับสนุนการแปลงจาก HTML และ CSS ได้แก่ PDFCrowd ซึ่งอ้างว่าสนับสนุน HTML5, CSS3 และ JavaScript อย่างกล้าหาญ อย่างไรก็ตาม ฉันไม่สามารถหารายละเอียดใดๆ เกี่ยวกับสิ่งที่ได้รับการสนับสนุนได้อย่างแน่นอน และหากข้อกำหนดของ Paged Media เป็นหรือไม่ นอกจากนี้ยังได้รับการกล่าวถึงในการตอบกลับทวีตของฉันคือ mPDF
ย้ายออกจาก HTML และ CSS
มีโซลูชันอื่นๆ อีกจำนวนหนึ่งที่เลิกใช้ HTML และ CSS และต้องการให้คุณสร้างเอาต์พุตเฉพาะสำหรับเครื่องมือ คู่แข่ง JavaScript สองสามรายการมีดังนี้:
- jsPDF
- pdfmake
เบราว์เซอร์หัวขาด + การบันทึกเป็น PDF ครั้งหนึ่งเคยเป็นตัวเลือกแรกของฉัน แต่ให้ผลลัพธ์ย่อยเสมอสำหรับสิ่งอื่นที่ไม่ใช่เอกสารหน้าเดียว เราเปลี่ยนไปใช้ https://t.co/3o8Ce23F1t สำหรับรายงานหลายหน้าซึ่งใช้ความพยายามค่อนข้างมาก แต่ก็คุ้มค่าในที่สุด!
– JimmyJoy (@jimle_uk) วันที่ 15 กุมภาพันธ์ 2019
คำแนะนำ
นอกเหนือจากแนวทางที่ใช้ JavaScript ซึ่งจะทำให้คุณต้องสร้างการนำเสนอเนื้อหาของคุณสำหรับการพิมพ์ที่แตกต่างไปจากเดิมอย่างสิ้นเชิง ความงามของโซลูชันเหล่านี้จำนวนมากคือสามารถใช้แทนกันได้ หากโซลูชันของคุณใช้การเรียกใช้เครื่องมือบรรทัดคำสั่ง และส่งผ่านเครื่องมือนั้น HTML, CSS และ JavaScript บางส่วน การสลับระหว่างเครื่องมือต่างๆ ค่อนข้างตรงไปตรงมา
ในระหว่างการเขียนบทความนี้ ฉันยังได้ค้นพบเครื่องห่อ Python ที่สามารถเรียกใช้เครื่องมือต่างๆ ได้มากมาย (โปรดทราบว่าคุณต้องมีเครื่องมือติดตั้งอยู่แล้ว อย่างไรก็ตาม นี่อาจเป็นวิธีที่ดีในการทดสอบเครื่องมือต่างๆ ในเอกสารตัวอย่าง)
สำหรับการสนับสนุน Paged Media และการแตกแฟรกเมนต์ Prince, Antenna House และ PDFReactor จะออกมาด้านบน ในฐานะที่เป็นผลิตภัณฑ์เชิงพาณิชย์ พวกเขายังมาพร้อมกับการสนับสนุน หากคุณมีงบประมาณ หน้าที่ซับซ้อนในการพิมพ์เป็น PDF และข้อจำกัดของคุณคือเวลาสำหรับนักพัฒนา คุณมักจะพบว่าสิ่งเหล่านี้เป็นเส้นทางที่เร็วที่สุดเพื่อให้การสร้าง PDF ของคุณทำงานได้ดี
อย่างไรก็ตาม ในหลายกรณี เครื่องมือฟรีจะทำงานได้ดีสำหรับคุณ หากความต้องการของคุณตรงไปตรงมามาก wkhtmltopdf หรือโซลูชัน Chrome และ Puppeteer แบบไม่มีส่วนหัวแบบพื้นฐานอาจช่วยคุณได้ ดูเหมือนว่าจะใช้ได้กับหลายคนที่ตอบกลับทวีตดั้งเดิมของฉัน
อย่างไรก็ตาม หากคุณพบว่าตัวเองกำลังประสบปัญหาในการได้ผลลัพธ์ที่ต้องการ โปรดทราบว่าอาจเป็นข้อจำกัดในการพิมพ์เบราว์เซอร์ และไม่ใช่สิ่งที่คุณทำผิดพลาด ในกรณีที่คุณต้องการการสนับสนุน Paged Media มากกว่านี้ แต่ไม่สามารถหาซื้อผลิตภัณฑ์เชิงพาณิชย์ได้ ให้ดูที่ WeasyPrint
ฉันหวังว่านี่จะเป็นบทสรุปที่มีประโยชน์ของเครื่องมือสำหรับสร้าง PDF จากเว็บแอปพลิเคชันของคุณ หากไม่มีอย่างอื่น แสดงว่ามีตัวเลือกมากมาย หากตัวเลือกแรกของคุณทำงานได้ไม่ดี
โปรดเพิ่มประสบการณ์และข้อเสนอแนะของคุณเองในความคิดเห็น นี่เป็นหนึ่งในสิ่งที่พวกเราหลายคนต้องเผชิญ และการแบ่งปันประสบการณ์ส่วนตัวอาจเป็นประโยชน์อย่างเหลือเชื่อ
อ่านเพิ่มเติม
บทสรุปของแหล่งข้อมูลและเครื่องมือต่างๆ ที่กล่าวถึงในบทความนี้ พร้อมด้วยแหล่งข้อมูลที่เป็นประโยชน์อื่นๆ สำหรับการทำงานกับไฟล์ PDF จากเว็บแอปพลิเคชัน
ข้อมูลจำเพาะ
- โมดูลสื่อเพจ
- การแยกส่วน
บทความและแหล่งข้อมูล
- ออกแบบงานพิมพ์ด้วย CSS
- ทำลายกล่องด้วยการแยกส่วน CSS
- คำแนะนำเกี่ยวกับสถานะของรูปแบบการพิมพ์ในปี 2018
- เริ่มต้นใช้งาน Headless Chrome และ Puppeteer
- print-css.rocks
เครื่องมือ
- wkhtmltopdf
- paged.js
- Vivliostyle
- เจ้าชาย
- บ้านเสาอากาศ
- PDFReactor
- DocRaptor
- WeasyPrint
- PDFCrowd
- mPDF
- jsPDF
- pdfmake
- ผลิตและเผยแพร่เซิร์ฟเวอร์