拆分 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 不给拆可以理解,但是否接受是另外一回事了。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注