用Adobe PDF Library SDK拆分PDF
拆分 PDF 的关键函数是 PDDocInsertPages。
void PDDocInsertPages(PDDoc doc, ASInt32 mergeAfterThisPage, PDDoc doc2, ASInt32 startPage, ASInt32 numPages, ASUns16 insertFlags, ProgressMonitor progMon, void * progMonClientData, CancelProc cancelProc, void *cancelProcClientData);
这个函数可以将一个 PDF 中的某几页插入到另一个 PDF 中。如果另一个 PDF 是个新建的空 PDF,那就实现了拆分 PDF 的目的。
示例主要代码:
#include <iostream> #include "Wrapper.h" #include "APDFLib.h" using namespace std; int main() { APDFLib lib; if (lib.hasError()) { lib.printError(); return -1; } DURING const wchar_t* filename = LR"(d:\Temp\test.pdf)"; WPDDoc doc(filename); int count = doc.GetNumPages(); for (int i = 0; i < count; ++i) { WPDDoc page; page.InsertPages(PDLastPage, doc, i, 1, PDInsertThreads); wchar_t buffer[256] = { 0 }; wsprintf(buffer, LR"(d:\Temp\aa\split_%d.pdf)", i + 1); PDSaveFlags saveFlags = PDSaveFull; page.Save(saveFlags, WASText(buffer)); } HANDLER ASErrorCode errCode = ERRORCODE; char errStr[256] = { 0 }; cerr << "Error: " << ASGetErrorString(errCode, errStr, 256) << endl; END_HANDLER return 0; }
相关代码 Wrapper.h
#include <PDCalls.h> #include <ASCalls.h> #include <ASExtraCalls.h> #include <DLExtrasCalls.h> #include <PDFLExpT.h> #include <PDFLCalls.h> class WASText { public: WASText(const wchar_t* text) : m_text(nullptr) { m_text = ASTextFromUnicode((ASUTF16Val*)text, kUTF16HostEndian); } ~WASText() { if (m_text) { ASTextDestroy(m_text); } } operator ASText() const { return m_text; } private: ASText m_text; }; class WASPathName { public: WASPathName(const WASText& text) : m_path(nullptr) { m_path = ASFileSysCreatePathFromDIPathText(nullptr, text, nullptr); } ~WASPathName() { if (m_path) { ASFileSysReleasePath(nullptr, m_path); } } operator ASPathName() const { return m_path; } private: ASPathName m_path; }; class WPDDoc { public: WPDDoc() : m_doc(nullptr) { m_doc = PDDocCreate(); } WPDDoc(const wchar_t* filename) : WPDDoc(WASPathName(filename)) { } WPDDoc(const WASPathName& filename) : m_doc(nullptr) { m_doc = PDDocOpen(filename, nullptr, nullptr, false); } ~WPDDoc() { if (m_doc) { PDDocClose(m_doc); } } operator PDDoc() const { return m_doc; } size_t GetNumPages() const { return PDDocGetNumPages(m_doc); } void InsertPages(ASInt32 mergeAfterThisPage, WPDDoc doc2, ASInt32 startPage, ASInt32 numPages, ASUns16 insertFlags = PDInsertAll, ProgressMonitor progMon = nullptr, void* progMonClientData = nullptr, CancelProc cancelProc = nullptr, void* cancelProcClientData = nullptr) { PDDocAcquire(doc2); PDDocInsertPages(m_doc, mergeAfterThisPage, doc2, startPage, numPages, insertFlags, progMon, progMonClientData, cancelProc, cancelProcClientData); } void Save( PDSaveFlags saveFlags, WASPathName newPath, ASFileSys fileSys = nullptr, ProgressMonitor progMon = nullptr, void* progMonClientData = nullptr) { PDDocSave(m_doc, saveFlags, newPath, fileSys, progMon, progMonClientData); } private: PDDoc m_doc; };
APDFLib 参考官方例子。
Adobe PDF Library SDK 兼容性还是不太好,遇到有 PDF 出现“Unrecognized object name.”错误,无法拆分,但用福昕的 SDK 是可以拆的。
另外,如果 PDF 内有权限限制,不可以编辑, Adobe 的 SDK 会出现“This operation is not permitted.”错误,用福昕的 SDK 又是可以拆的;权限问题 Adobe 不给拆可以理解,但是否接受是另外一回事了。