PDFlibPas แปลงเนื้อหา PDF เป็นสองรูปแบบที่แก้ไขได้โดยไม่ต้องใช้ระบบอัตโนมัติของ Office ExportPageMarkdown และ ExportDocumentMarkdown คืนค่า Markdown เชิงความหมายพร้อมหัวข้อที่อนุมานได้ รายการแบบมีลำดับและไม่มีลำดับ และตารางแบบ pipe ในขณะที่ SaveDOCXToFile และ SaveDOCXToStream เขียนแพ็กเกจ WordprocessingML ที่ประกอบด้วยย่อหน้า หัวข้อ การกำหนดหมายเลขรายการแบบเนทีฟ ตารางที่ตรวจพบ การจัดสไตล์ฟอนต์ การขึ้นหน้าใหม่ และรูปภาพ PNG ที่จัดตำแหน่งแล้ว
ทั้งสองรูปแบบทำงานทั้งหมดด้วย Pascal บนเซิร์ฟเวอร์ โดยไม่ต้องติดตั้ง Word และไม่ต้องใช้ COM ข้อจำกัดนี้เองคือเหตุผลที่ฟีเจอร์นี้อยู่ในไลบรารี PDF แทนที่จะอยู่ในเครื่องมือเดสก์ท็อป
เหตุใดการแปลง “PDF เป็น Word” จึงยากอย่างแท้จริง
เพราะหน้า PDF ไม่ได้บรรจุย่อหน้าอยู่จริง แต่บรรจุตัวดำเนินการแสดงข้อความที่วางกลุ่มกลิฟลงบนพิกัดต่าง ๆ ตามลำดับที่ผู้สร้างไฟล์เขียนออกมา โดยไม่มีข้อบังคับใดว่าต้องระบุว่ากลุ่มสองกลุ่มอยู่ในประโยคเดียวกัน นับประสาอะไรกับการอยู่ในรายการเดียวกัน รูปแบบนี้ถูกออกแบบมาเพื่อบรรยายหน้ากระดาษที่พิมพ์ออกมาได้อย่างแม่นยำ และมันทำสำเร็จด้วยการทิ้งโครงสร้างที่สร้างหน้านั้นขึ้นมาไปเลย
ดังนั้นตัวแปลงทุกตัวจึงต้องสร้างสิ่งที่ระบบสร้างไฟล์ทิ้งไปขึ้นมาใหม่ การจัดกลุ่มบรรทัดมาจากระยะห่างแนวตั้งและการเรียงตามเส้นฐาน ขอบเขตย่อหน้ามาจากการเปลี่ยนระยะห่างและการเยื้อง หัวข้อคือบรรทัดที่ฟอนต์ใหญ่กว่าหรือหนากว่าเนื้อหาปกติและแยกตัวออกจากส่วนที่ตามมา รายการคือชุดย่อหน้าที่ขึ้นต้นด้วยสัญลักษณ์บุลเล็ตหรือรูปแบบตัวเลข ตารางคือตารางกริดของบล็อกข้อความที่ขอบเรียงตัวตรงกันทั้งแถวและคอลัมน์ ทุกอย่างที่กล่าวมาล้วนเป็นการอนุมาน และการอนุมานหมายถึงผลลัพธ์ที่ดีสำหรับเอกสารที่เป็นไปตามธรรมเนียมการจัดพิมพ์ทั่วไป และผลลัพธ์ปานกลางสำหรับเอกสารที่ไม่เป็นไปตามนั้น
PDF แบบมีแท็กเป็นข้อยกเว้นที่สำคัญมาก เมื่อเอกสารมีโครงสร้างต้นไม้ บทบาทของย่อหน้า หัวข้อ รายการ และตารางจะถูกบันทึกไว้แทนการเดา นี่คือเหตุผลที่งานด้านการเข้าถึงที่อธิบายไว้ใน โครงสร้างการเข้าถึงของ PDF แบบมีแท็ก ส่งผลดีต่อคุณภาพการแปลงด้วย ถ้าคุณควบคุมระบบสร้างไฟล์ได้ การติดแท็กในผลลัพธ์คือสิ่งเดียวที่คุ้มค่าที่สุดที่คุณทำได้เพื่อทุกคนที่ต้องแปลงไฟล์นั้นในภายหลัง
การส่งออก Markdown ทีละหน้า
เส้นทาง Markdown คือทางเลือกที่ควรใช้เมื่อปลายทางเป็นไปป์ไลน์ข้อความ เช่น เว็บไซต์เอกสารประกอบ ดัชนีค้นหา หรือคลังข้อมูลสำหรับผู้ช่วย AI ตัวเลือกเป็นบิตมาสก์: PDF_MARKDOWN_INCLUDE_PAGE_MARKERS, PDF_MARKDOWN_DETECT_HEADINGS, PDF_MARKDOWN_PRESERVE_STYLES โดย PDF_MARKDOWN_DEFAULT รวมทั้งสามอย่างเข้าด้วยกัน
var
Pdf: TPDFlib;
Md: WideString;
begin
Pdf := TPDFlib.Create;
try
Pdf.LoadFromFile('handbook.pdf', '');
// หนึ่งหน้า ในรูปแบบสตริง
Md := Pdf.ExportPageMarkdown(1, PDF_MARKDOWN_DEFAULT);
// ช่วงหน้า สตรีมลงดิสก์เป็น UTF-8 โดยไม่มี BOM
Pdf.SaveMarkdownToFile('1-40',
PDF_MARKDOWN_DETECT_HEADINGS or PDF_MARKDOWN_PRESERVE_STYLES,
'handbook.md');
finally
Pdf.Free;
end;
end;
เครื่องหมายกำกับหน้าคุ้มค่ามากในงานด้านการสืบค้นข้อมูล ชิ้นส่วนข้อความที่มีหมายเลขหน้าต้นทางกำกับไว้จะสามารถอ้างอิงได้อย่างแม่นยำ และผู้อ่านที่ตามลิงก์อ้างอิงไปก็จะไปถึงตำแหน่งที่ข้อความนั้นอยู่จริง ปิดใช้งานเมื่อ Markdown มีไว้สำหรับให้คนอ่าน ซึ่งขอบเขตหน้าจากเลย์เอาต์ต้นฉบับจะกลายเป็นสิ่งรบกวน
จุดเข้าใช้งานแบบสตรีมสำคัญมากสำหรับเอกสารขนาดใหญ่ SaveMarkdownToStream และ SaveMarkdownToFile เขียน UTF-8 ทีละหน้าและไม่บัฟเฟอร์ผลลัพธ์ทั้งหมดไว้ก่อน ดังนั้นคู่มือ 900 หน้าจึงไม่กลายเป็นสตริง 900 หน้าในหน่วยความจำก่อน การไม่มีเครื่องหมายลำดับไบต์ก็เป็นการตั้งใจเช่นกัน เพราะ BOM ในไฟล์ Markdown ทำให้ตัวสร้างเว็บไซต์แบบสแตติกและเครื่องมือ diff จำนวนไม่น้อยสับสน
DOCX โดยไม่ต้องมี Office บนเครื่อง
ตัวเขียน DOCX สร้างแพ็กเกจขึ้นมาเอง: รายการ ZIP ที่เขียนด้วย Deflate ดิบพร้อมการตรวจสอบ CRC ส่วนต่าง ๆ ของ WordprocessingML และความสัมพันธ์ที่เชื่อมโยงสิ่งเหล่านั้นเข้าด้วยกัน ไม่มีการเรียกเข้าไปใน Word เลย นั่นหมายความว่าการแปลงทำงานได้บนเซิร์ฟเวอร์แบบ headless ในบัญชีบริการ ในคอนเทนเนอร์ และในทุกที่ที่ระบบอัตโนมัติของ Office ไม่มีลิขสิทธิ์ ไม่เสถียร หรือถูกห้ามใช้
var
Pdf: TPDFlib;
Target: TFileStream;
begin
Pdf := TPDFlib.Create;
Target := TFileStream.Create('handbook.docx', fmCreate);
try
Pdf.LoadFromFile('handbook.pdf', '');
Pdf.SaveDOCXToStream('1-40',
PDF_DOCX_INCLUDE_IMAGES or PDF_DOCX_DETECT_HEADINGS or
PDF_DOCX_PRESERVE_STYLES or PDF_DOCX_PRESERVE_PAGE_BREAKS,
Target);
finally
Target.Free;
Pdf.Free;
end;
end;
ข้อมูลรูปภาพจะถูกเขียนขณะที่แต่ละหน้าถูกประมวลผล แทนที่จะรวบรวมแล้วต่อท้ายในตอนจบ ดังนั้นหน่วยความจำสูงสุดจึงติดตามแค่หนึ่งหน้าแทนที่จะเป็นทั้งเอกสาร ลำดับหน้าที่ชัดเจนถูกรักษาไว้ และหน้า PDF ที่ถูกเลือกไว้จะถูกคืนค่ากลับหลังจากนั้น ซึ่งสำคัญเมื่อการส่งออกเป็นเพียงขั้นตอนหนึ่งในงานที่ยาวกว่าซึ่งมีการเลือกหน้าไว้ด้วยเหตุผลอื่น
การแพ็กเกจแบบกำหนดผลลัพธ์แน่นอนให้ประโยชน์อะไร
การทำซ้ำผลลัพธ์ได้เหมือนเดิมทุกไบต์ การแปลงข้อมูลนำเข้าเดียวกันด้วยตัวเลือกเดียวกันสองครั้งจะได้แพ็กเกจเดียวกัน หมายความว่าคุณสามารถแฮชผลลัพธ์เพื่อตรวจจับการเปลี่ยนแปลง เปรียบเทียบเอกสารที่สร้างขึ้นสองรุ่น และแคชได้อย่างมั่นใจโดยไม่ต้องกังวลว่าข้อมูลนำเข้าที่เหมือนกันจะได้สิ่งที่สร้างขึ้นต่างกัน
ระบบอัตโนมัติของ Office ให้คำมั่นแบบนี้ไม่ได้ มันฝังไทม์สแตมป์ ตัวระบุรุ่นแก้ไข และเมทาดาทาที่ขึ้นกับเครื่องไว้ด้วย ทำให้เอกสารเดียวกันที่แปลงสองครั้งต่างกันในแบบที่ทำลายการแฮช เหตุผลเดียวกันนี้ขับเคลื่อนตัวระบุไฟล์แบบกำหนดผลลัพธ์แน่นอนที่กล่าวถึงใน รหัส PDF แบบกำหนดผลลัพธ์แน่นอนสำหรับการบิลด์ที่ทำซ้ำได้: เมื่อผลลัพธ์ทำซ้ำได้ การตรวจสอบก็กลายเป็นการเปรียบเทียบแทนที่จะเป็นการตรวจสอบเชิงลึก
ผลลัพธ์ดีตรงไหน และไม่ดีตรงไหน
ควรบอกผู้ใช้ตรง ๆ ในเรื่องนี้ เพราะคุณภาพการแปลงขึ้นอยู่กับข้อมูลนำเข้ามากกว่าตัวแปลงเอง PDF แบบมีแท็กและเอกสารธุรกิจที่สร้างขึ้นอย่างสะอาด เช่น ใบแจ้งหนี้ รายงาน สัญญา จะแปลงได้ดี: หัวข้อกลายเป็นหัวข้อ ตารางยังคงอยู่ รายการเรียงหมายเลขใหม่ถูกต้องใน Word เลย์เอาต์วิชาการแบบสองคอลัมน์แปลงได้ในระดับที่ยอมรับได้ถ้ารูปทรงเรขาคณิตของคอลัมน์สม่ำเสมอ ตารางที่คร่อมการขึ้นหน้าใหม่จะถูกประกอบขึ้นใหม่ด้วยการอนุมานและบางครั้งก็ถูกแยกออก วัสดุการตลาดที่ออกแบบมาอย่างหนัก ซึ่งวางข้อความเพื่อเอฟเฟกต์ทางสายตามากกว่าลำดับการอ่าน จะแปลงได้ไม่ดี และการอนุมานมากแค่ไหนก็แก้ไขเรื่องนี้ไม่ได้
เอกสารที่สแกนแล้วเป็นกรณีที่แยกออกไปต่างหากโดยสิ้นเชิง หน้าที่เป็นภาพขนาดใหญ่ภาพเดียวไม่มีอ็อบเจกต์ข้อความอยู่เลย จึงไม่มีอะไรให้ส่งออกจนกว่าจะมีเลเยอร์ข้อความอยู่ก่อน เส้นทาง OCR ที่สร้างเลเยอร์นั้นขึ้นมาเป็นข้อกำหนดเบื้องต้น ไม่ใช่ตัวเลือก ก่อนรันชุดข้อมูลขนาดใหญ่ ให้สุ่มตัวอย่างไฟล์ตัวแทนสักสิบกว่าไฟล์แล้วดูผลลัพธ์ และควรพิจารณาแจกแจงองค์ประกอบในหน้าก่อน ตามที่อธิบายไว้ใน การค้นหาข้อความและการแจกแจงองค์ประกอบในหน้า เพื่อดูว่าหน้าเหล่านั้นมีอะไรอยู่จริง
สำหรับไปป์ไลน์ผู้ช่วย AI และการสืบค้นข้อมูล เส้นทาง Markdown มักเป็นเป้าหมายที่ดีกว่า: หัวข้อกลายเป็นขอบเขตชิ้นข้อมูล ตารางยังคงอ่านได้ในรูปแบบ pipe table และเครื่องหมายกำกับหน้าให้ตำแหน่งที่อ้างอิงได้แก่ทุกชิ้นข้อมูล สำหรับการแก้ไขโดยมนุษย์ DOCX คือคำตอบ เพราะสิ่งที่ผู้ใช้ต้องการไม่ใช่ตัวข้อความ แต่คือความสามารถในการเปลี่ยนแปลงมัน
PDFlibPas เป็นไลบรารี PDF สำหรับ Delphi, C++Builder และ Lazarus พร้อมอินเทอร์เฟซ DLL และ ActiveX ที่ตรงกัน ทำให้ฟังก์ชันส่งออกชุดเดียวกันใช้งานได้จาก C#, C++ หรือโฮสต์สคริปต์อื่น ๆ เอกสารฉบับเต็มและรุ่นทดลองใช้งานอยู่ที่ หน้าไลบรารี PDF สำหรับ Delphi ของ PDFlibPas