วิธีทำงานกับเอกสาร PDF ใน C++
Aspose.PDF FOSS for C++ คือไลบรารี C++20 ที่ใช้ใบอนุญาต MIT, ไม่พึ่งพาไลบรารีอื่น, สร้างและลิงก์ด้วย CMake — ไม่มีการนำเข้าโดยตัวจัดการแพ็กเกจให้เพิ่ม คู่มือฉบับนี้จะอธิบายขั้นตอนการทำงานหลักที่เน้น Document: เปิด PDF ที่มีอยู่, ตรวจสอบหน้าและเมตาดาต้า, ดึงข้อความ, และเรนเดอร์หน้าหนึ่งเป็นภาพ raster.
คู่มือแบบทีละขั้นตอน
ขั้นตอนที่ 1: ติดตั้งแพ็กเกจ
โคลนรีโพซิทอรีและเพิ่มเข้าไปในโปรเจกต์ CMake ของคุณเป็นซับไดเรกทอรี:
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.gitadd_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)หรือกำหนดค่าและสร้างเป็นแอปพลิเคชันอิสระ:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildตรวจสอบว่า toolchain ทำงานได้โดยคอมไพล์โปรแกรมขนาดเล็กที่อ้างอิงกับหัวไฟล์:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK - pages: " << doc.Pages().Count() << "\n";
}การสร้างสำเร็จที่พิมพ์ pages: 0 สำหรับ Document ที่เพิ่งสร้างขึ้นและว่างเปล่า ยืนยันว่าห้องสมุดเชื่อมต่ออย่างถูกต้อง.
ขั้นตอนที่ 2: นำเข้าคลาสที่จำเป็น
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
#include <aspose/pdf/page.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/text_absorber.hpp>
#include <aspose/pdf/bmp_device.hpp>
#include <aspose/pdf/resolution.hpp>
#include <fstream>
#include <iostream>ขั้นตอนที่ 3: เปิดเอกสาร PDF และนับจำนวนหน้าของมัน
สร้าง Document จากเส้นทางไฟล์เพื่อเปิด PDF ที่มีอยู่แล้ว. Document::Pages() คืนค่า PageCollection และ Count() รายงานจำนวนหน้าที่มี:
Aspose::Pdf::Document doc("input.pdf");
std::cout << "Page count: " << doc.Pages().Count() << "\n";ขั้นตอนที่ 4: อ่านเมตาดาต้าเอกสาร
Document::Info() คืนค่าอ็อบเจ็กต์ DocumentInfo ที่มีตัวเข้าถึงแบบอ่าน/เขียนที่กำหนดประเภทสำหรับรายการพจนานุกรมมาตรฐานของ /Info:
auto& info = doc.Info();
std::cout << "Title: " << info.Title() << "\n";
std::cout << "Author: " << info.Author() << "\n";
std::cout << "Producer: " << info.Producer() << "\n";ขั้นตอนที่ 5: ดึงข้อความจากหน้า
Aspose::Pdf::Text::TextAbsorber เดินผ่าน Document หรือ Page เดียวและสะสมข้อความที่พบ; Text() คืนค่าผลลัพธ์ต่อมา. PageCollection เริ่มนับจาก 1 ดังนั้น Pages()[1] คือหน้าที่หนึ่ง:
auto page = doc.Pages()[1];
Aspose::Pdf::Text::TextAbsorber absorber;
absorber.Visit(page);
std::cout << absorber.Text() << "\n";Visit() ยังรับ Document ทั้งหมดโดยตรง (absorber.Visit(doc)) เมื่อคุณต้องการให้ข้อความของทุกหน้าถูกต่อเนื่องกันแทนที่จะเป็นหน้าเดียว.
ขั้นตอนที่ 6: เรนเดอร์หน้าเป็นภาพแรสเตอร์
BmpDevice เรนเดอร์ Page ไปเป็นภาพ BMP ที่ไม่ได้บีบอัด ตัวสร้างของมันรับ Resolution ที่ควบคุม DPI ของผลลัพธ์ และ Process() เขียนไบต์ที่เรนเดอร์แล้วไปยัง std::ostream ใด ๆ:
Aspose::Pdf::Devices::BmpDevice device(Aspose::Pdf::Devices::Resolution(150));
std::ofstream imageOut("page1.bmp", std::ios::binary);
device.Process(page, imageOut);ขั้นตอนที่ 7: อัปเดตเมทาดาต้าและบันทึกเอกสาร
ตัวตั้งค่าบน DocumentInfo ทำการจัดเตรียมการเปลี่ยนแปลงที่ถูกสั่งล้างในครั้งต่อไปที่ Save() ทำงานบน Document ที่เป็นเจ้าของ:
doc.Info().Title("Processed by Aspose.PDF FOSS for C++");
doc.Save("output.pdf");ปัญหาทั่วไปและการแก้ไข
Accessing Pages()[0] throws std::out_of_range
PageCollection มีการจัดเลขตั้งแต่ 1 (1-indexed), สอดคล้องกับ semantics ของ Aspose.PDF ตามมาตรฐาน — หน้าแรกคือ Pages()[1]. การใช้ดัชนีที่ต่ำกว่า 1 หรือสูงกว่า Count() จะทำให้เกิดข้อผิดพลาด.
TextAbsorber::Text() คืนค่าสตริงว่าง
Text() คืนค่าที่สะสมจากการเรียก Visit() ล่าสุด. ยืนยันว่า Visit() ถูกเรียกจริงก่อนที่จะอ่าน Text(), และตรวจสอบว่าหน้าหรือเอกสารที่คุณเปิดมีข้อความที่สามารถดึงออกได้ ไม่ใช่เพียงภาพสแกน.
ไฟล์ BMP ที่เรนเดอร์มีขนาดเล็กกว่าที่คาดหรือดูเป็นค่าว่าง
ค่าต่ำของ Resolution ทำให้ได้ภาพเรสเตอร์ขนาดเล็ก เพิ่มค่า DPI ที่ส่งให้กับ Resolution — ตัวอย่างเช่น Resolution(300) สำหรับผลลัพธ์คุณภาพการพิมพ์ — และตรวจสอบว่าดัชนีหน้าที่ส่งให้กับ Process() เป็นหน้าที่คุณต้องการจริงหรือไม่.
DocumentInfo ฟิลด์ที่อ่านกลับเป็นสตริงว่าง
ผู้ผลิต PDF ทุกคนไม่ได้เขียนรายการ /Info มาตรฐาน ตรวจสอบค่าใน Producer() และ Creator() ว่าว่างหรือไม่ก่อนสันนิษฐานว่าการสกัดเมตาดาต้าล้มเหลว — สตริงว่างเป็นผลลัพธ์ที่กำหนดไว้สำหรับคีย์ที่ไม่มี.
การเปลี่ยนแปลงที่ทำด้วย Info().Title(...) ไม่ปรากฏในไฟล์ที่บันทึก
การเปลี่ยนแปลงของ DocumentInfo จะถูกจัดเก็บชั่วคราวในหน่วยความจำและจะถูกบันทึกจริงเฉพาะครั้งถัดไปที่ Save() ทำงานบนอินสแตนซ์ Document เดียวกัน ให้แน่ใจว่าการแก้ไขเมทาดาต้าจะเกิดขึ้นก่อน Save() ไม่ใช่หลังจากนั้น.
คำถามที่พบบ่อย
การจัดอันดับหน้าเป็นแบบศูนย์เป็นฐานหรือหนึ่งเป็นฐานใน Aspose.PDF FOSS สำหรับ C++?
หนึ่งเป็นฐาน doc.Pages()[1] คือหน้าที่แรกเสมอ.
สามารถ TextAbsorber ดึงข้อความจากหน้าเดียวแทนที่จะดึงจากเอกสารทั้งหมดได้หรือไม่?
ใช่. Visit() มีการโอเวอร์โหลดให้รับได้ทั้ง Document — ซึ่งดึงข้อความของทุกหน้า — หรือ Page หนึ่งหน้า ซึ่งดึงข้อความของหน้านั้นเท่านั้น.
ฉันต้องเรียก Save() หรือไม่ หากฉันเพียงแค่อ่านข้อมูลจากเอกสาร?
ไม่. Save() จำเป็นต้องใช้เฉพาะหลังจากทำการเปลี่ยนแปลงที่ต้องเขียนกลับไปยังไฟล์ เช่น การแก้ไขฟิลด์ DocumentInfo การอ่านจำนวนหน้า การดึงข้อความ หรือการเรนเดอร์หน้า ไม่ได้ทำให้เอกสารเปลี่ยนแปลง.
ฉันจะควบคุมความละเอียดของหน้าที่เรนเดอร์ได้อย่างไร?
ส่งค่า Resolution ไปยังคอนสตรัคเตอร์ของอุปกรณ์ — ตัวอย่างเช่น Resolution(150) สำหรับ 150 DPI. ค่าที่สูงกว่าจะสร้างภาพเรสเตอร์ที่ใหญ่ขึ้นและมีความละเอียดสูงกว่า.
รูปแบบใดที่ BmpDevice ผลิต?
ภาพ BMP ที่ไม่ได้บีบอัดซึ่งเขียนโดยตรงไปยัง std::ostream ที่ส่งให้ Process().