PDFium VCL пÑедлага обединÑване на PDF ÑÑез един единÑÑвен меÑод: ImportPages. ÐоделÑÑ Ð²Ð¸Ð½Ð°Ð³Ð¸ е един и ÑÑÑ: ÑÑздаване на пÑазен кÑаен докÑменÑ, оÑваÑÑне на вÑеки изÑ
оден Ñайл, извикване на ImportPages за копиÑане на ÑÑÑаниÑиÑе, заÑваÑÑне на изÑоÑника и повÑаÑÑне на пÑоÑеÑа. ÐогаÑо ÑикÑлÑÑ Ð¿ÑиклÑÑи, SaveAs запиÑва ÑезÑлÑаÑа на диÑка. ÐÑма ÑпеÑиален Ñежим за обединÑване или допÑлниÑелни конÑигÑÑаÑии. СложноÑÑÑа Ñе кÑие в гÑаниÑниÑе ÑлÑÑаи, каÑо нÑкои Ð¾Ñ ÑÑÑ
Ð¼Ð¾Ð³Ð°Ñ Ð´Ð° Ð´Ð¾Ð²ÐµÐ´Ð°Ñ Ð´Ð¾ неоÑаквани пÑоблеми.
ÐÑновниÑÑ ÑикÑл
ÐÑжни Ñа ви Ñамо две инÑÑанÑии на TPdf. ÐднаÑа ÑÑдÑÑжа кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑменÑ, ÑÑздаден каÑо пÑазен Ñ CreateDocument. ÐÑÑгаÑа оÑваÑÑ Ð¿Ð¾ÑледоваÑелно вÑеки изÑ
оден Ñайл. Ðо-Ð´Ð¾Ð»Ñ Ðµ показана пÑоÑедÑÑа, коÑÑо пÑиема ÑпиÑÑк Ñ Ñайлови пÑÑиÑа и запиÑва Ð¾Ð±ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑезÑлÑÐ°Ñ Ð² един Ð¾Ð±Ñ Ð¿ÑÑ:
procedure MergeFiles(const FileList: TStrings; const OutputPath: string);
var
PdfDest, PdfSrc: TPdf;
InsertAt, I: Integer;
begin
PdfDest := TPdf.Create(nil);
PdfSrc := TPdf.Create(nil);
try
PdfDest.CreateDocument;
InsertAt := 1; // ImportPages uses 1-based destination position
for I := 0 to FileList.Count - 1 do
begin
PdfSrc.FileName := FileList[I];
PdfSrc.Active := True;
if not PdfSrc.Active then
raise Exception.CreateFmt('Cannot open: %s', [FileList[I]]);
PdfDest.ImportPages(
PdfSrc,
'1-' + IntToStr(PdfSrc.PageCount), // full document range
InsertAt);
Inc(InsertAt, PdfSrc.PageCount);
PdfSrc.Active := False;
end;
PdfDest.SaveAs(OutputPath);
finally
PdfSrc.Free;
PdfDest.Free;
end;
end;
Ðве неÑа в Ñози код Ñе пÑопÑÑÐºÐ°Ñ Ð»ÐµÑно пÑи пÑÑво ÑеÑене. ÐÑÑвоÑо е как PDFium ÑÑобÑава за гÑеÑки пÑи заÑеждане. Active := True никога не пÑедизвиква изклÑÑение: ако ÑайлÑÑ Ð»Ð¸Ð¿Ñва, е повÑеден или е заÑиÑен Ñ Ð¿Ð°Ñола, PDFium ÑÐ»Ð°Ð²Ñ Ð³ÑеÑкаÑа вÑÑÑеÑно и оÑÑÐ°Ð²Ñ Active на ÑÑойноÑÑ False. Ðез изÑиÑнаÑа пÑовеÑка, повÑедениÑÑ Ñайл пÑоÑÑо Ñе бÑде изпÑÑÐ½Ð°Ñ Ð¾Ñ Ð¾Ð±ÐµÐ´Ð¸Ð½ÑванеÑо без никаква индикаÑÐ¸Ñ Ð² изÑ
Ð¾Ð´Ð½Ð¸Ñ ÑезÑлÑаÑ. ÐÑайниÑÑ PDF Ñе има по-малко ÑÑÑаниÑи Ð¾Ñ Ð¾ÑакваноÑо и нÑма да ÑазбеÑеÑе кой Ñайл е пÑиÑинил пÑоблема.
ÐÑоÑоÑо неÑо е бÑоÑÑÑÑ InsertAt. ТÑеÑиÑÑ Ð°ÑгÑÐ¼ÐµÐ½Ñ Ð½Ð° ImportPages е позиÑиÑÑа в кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ (базиÑана на 1), кÑдеÑо Ñе поÑÑÐ°Ð²Ñ Ð¿ÑÑваÑа импоÑÑиÑана ÑÑÑаниÑа. СÑаÑÑиÑанеÑо Ð¾Ñ 1 поÑÑÐ°Ð²Ñ Ð¿ÑÑÐ²Ð¸Ñ Ð¸Ð·Ñ
оден докÑÐ¼ÐµÐ½Ñ Ð² наÑалоÑо на инаÑе пÑазен Ñайл. След вÑеки изÑоÑник бÑоÑÑÑÑ Ñе ÑвелиÑава Ñ PdfSrc.PageCount, Ñака Ñе ÑледваÑаÑа паÑÑида ÑÑÑаниÑи Ñе Ð´Ð¾Ð±Ð°Ð²Ñ Ñлед поÑледнаÑа. Ðко забÑавиÑе да го ÑвелиÑиÑе, вÑеки ÑÐ»ÐµÐ´Ð²Ð°Ñ Ð¸Ð·ÑоÑник Ñе пÑезапиÑе ÑÑÑаниÑиÑе на позиÑÐ¸Ñ 1, оÑÑавÑйки ви Ñамо Ñ Ð¿Ð¾ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ Ð² ÑпиÑÑка.
ÐзбиÑаÑелни диапазони Ð¾Ñ ÑÑÑаниÑи
Ðе е необÑ
одимо да взимаÑе вÑÑка ÑÑÑаниÑа Ð¾Ñ Ð´Ð°Ð´ÐµÐ½ изÑоÑник. ÐизÑÑ Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°, подаден каÑо вÑоÑи аÑгÑменÑ, Ñледва пÑоÑÑ ÑоÑÐ¼Ð°Ñ ÑÑÑ Ð·Ð°Ð¿ÐµÑаи и ÑиÑеÑа: "1-3" взима ÑÑÑаниÑи Ð¾Ñ 1 до 3, "2,4,6" избиÑа ÑÑи конкÑеÑни ÑÑÑаниÑи, а "1-" ознаÑава Ð¾Ñ ÑÑÑаниÑа 1 до кÑÐ°Ñ Ð½Ð° докÑменÑа. ÐиапазониÑе Ð¼Ð¾Ð³Ð°Ñ Ð´Ð° Ñе комбиниÑÐ°Ñ Ð² един низ, Ñака Ñе "1-3,5,7-" пÑопÑÑка ÑÑÑаниÑи 4 и 6. ТÑк е важен един ÑÑнÑк моменÑ: номеÑаÑа винаги Ñе оÑнаÑÑÑ Ð·Ð° ÑÑÑаниÑиÑе в изÑ
Ð¾Ð´Ð½Ð¸Ñ Ð´Ð¾ÐºÑменÑ, запоÑвайки Ð¾Ñ 1, незавиÑимо кÑде Ñе Ð¿Ð¾Ð¿Ð°Ð´Ð½Ð°Ñ Ñези ÑÑÑаниÑи в кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑменÑ. Ðко иÑкаÑе ÑÑÑаниÑи Ð¾Ñ 40 до 50 Ð¾Ñ ÐºÐ°Ñалог Ñ Ð¾Ð±Ñо 200 ÑÑÑаниÑи, низÑÑ Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° ÑÑÑбва да бÑде "40-50", а не позиÑÐ¸Ñ ÑпÑÑмо Ñова, коеÑо веÑе е добавено в кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑменÑ.
// Extract cover plus a three-page executive summary from a long report
PdfSrc.FileName := 'annual-report.pdf';
PdfSrc.Active := True;
if PdfSrc.Active then
begin
// Page 1 is the cover; pages 3-5 are the summary
PdfDest.ImportPages(PdfSrc, '1,3-5', InsertAt);
Inc(InsertAt, 4); // 1 cover + 3 summary pages = 4 pages added
PdfSrc.Active := False;
end;
ÐогаÑо изÑиÑлÑваÑе ÑвелиÑениеÑо на InsertAt, бÑойÑе ÑÑÑаниÑиÑе, коиÑо дейÑÑвиÑелно ÑÑе импоÑÑиÑали, а не обÑÐ¸Ñ Ð±Ñой ÑÑÑаниÑи на изÑоÑника. Ðко подадеÑе '1,3-5', вие ÑÑе импоÑÑиÑали 4 ÑÑÑаниÑи, Ñака Ñе ÑвелиÑеÑе Ñ 4. УвелиÑаванеÑо Ñ PdfSrc.PageCount би оÑÑавило пÑазни позиÑии в кÑÐ°Ð¹Ð½Ð¸Ñ Ñайл и би поÑÑавило ÑледваÑÐ¸Ñ Ð¸Ð·Ñ
оден докÑÐ¼ÐµÐ½Ñ Ð¿Ð¾-напÑед вÑв Ñайла Ð¾Ñ Ð¿ÑедвиденоÑо.
Ðакво запазва ImportPages и какво не
СÑÑаниÑиÑе, копиÑани ÑÑез ImportPages, пÑенаÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾Ñо Ñи ÑÑдÑÑжание непокÑÑнаÑо. ТекÑÑ, векÑоÑна гÑаÑика, ÑаÑÑеÑни изобÑажениÑ, вгÑадени ÑÑиÑÑове и ÑоÑмÑлÑÑни XObjects Ñе пÑеÑ
вÑÑлÑÑ ÐºÐ°Ñо ÑаÑÑ Ð¾Ñ Ð¿Ð¾ÑоÑиÑе Ð¾Ñ ÑÑдÑÑжание на ÑÑÑаниÑаÑа. ÐноÑаÑииÑе на ниво ÑÑÑаниÑа, вклÑÑиÑелно коменÑаÑи, подÑеÑÑÐ°Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑиÑÑнки Ñ Ð¼Ð°ÑÑило, ÑÑÑо Ñе пÑеÑ
вÑÑлÑÑ, ÑÑй каÑо Ñе Ñе ÑÑÑ
ÑанÑÐ²Ð°Ñ Ð² ÑеÑника на ÑÑÑаниÑаÑа, а не на ниво докÑменÑ.
ÐеÑаданниÑе на ниво докÑÐ¼ÐµÐ½Ñ Ñа ÑазлиÑна иÑÑоÑиÑ. ÐизовеÑе за заглавие, авÑоÑ, Ñема и клÑÑови дÑми в Info ÑеÑника на изÑоÑника оÑÑÐ°Ð²Ð°Ñ Ð½Ð°Ð·Ð°Ð´. ÐÑайниÑÑ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ Ð·Ð°Ð¿Ð¾Ñва Ñ Ð¿Ñазни меÑаданни Ñлед CreateDocument, Ñака Ñе ако иÑкаÑе Ñези полеÑа да бÑÐ´Ð°Ñ Ð¿Ð¾Ð¿Ñлнени в Ð¾Ð±ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñайл, ÑÑÑбва да ги пÑиÑвоиÑе диÑекÑно на PdfDest пÑеди извикванеÑо на SaveAs. СвойÑÑваÑа Title, Author, Subject, Keywords и Creator в TPdf пÑÐ¸ÐµÐ¼Ð°Ñ Ð¾Ð±Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸ низове и Ñе запиÑÐ²Ð°Ñ Ð² Info ÑеÑника пÑи запазване.
ÐнÑеÑакÑивниÑе полеÑа на ÑоÑмÑлÑÑи Ñа по-Ñложни. ÐеÑиниÑииÑе на AcroForm полеÑаÑа живеÑÑ Ð² ÑеÑник на ниво докÑменÑ, а не в поÑоÑиÑе на оÑделниÑе ÑÑÑаниÑи. ÐогаÑо ImportPages копиÑа ÑÑÑаниÑа, ÑÑдÑÑжаÑа полеÑа на ÑоÑмÑлÑÑ, визÑалниÑÑ Ð²Ð¸Ð´ на Ñези полеÑа Ñе пÑеÑ
вÑÑлÑ, ÑÑй каÑо Ñе изобÑазÑва в поÑока Ð¾Ñ ÑÑдÑÑжание на ÑÑÑаниÑаÑа, но гÑаÑиÑниÑе компоненÑи (widgets), коиÑо ги пÑавÑÑ Ð¸Ð½ÑеÑакÑивни, Ñа ÑаÑÑ Ð¾Ñ AcroForm ÑÑÑÑкÑÑÑаÑа и не Ñе пÑенаÑÑÑ. ÐÑи ÑипиÑно обединÑване ÑекÑÑово поле Ð¾Ñ Ð¸Ð·Ñ
оден докÑÐ¼ÐµÐ½Ñ Ñе показва ÑÑойноÑÑÑа, коÑÑо е имало в моменÑа на импоÑÑиÑанеÑо, но нÑма да може да Ñе ÑедакÑиÑа в Ð¾Ð±ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñайл. Ðко имаÑе нÑжда полеÑаÑа да оÑÑÐ°Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñлваеми, ÑÑÑбва да ги изгладиÑе (flatten) вÑв вÑеки изÑ
оден докÑÐ¼ÐµÐ½Ñ Ð¿Ñеди импоÑÑиÑанеÑо: Ñова вгÑажда ÑекÑÑиÑе ÑÑойноÑÑи в поÑока Ð¾Ñ ÑÑдÑÑжание и пÑемаÑ
ва инÑеÑакÑивноÑо наÑлагване, оÑигÑÑÑвайки ÑиÑÑ Ð²Ð¸Ð·Ñален ÑезÑлÑÐ°Ñ Ð±ÐµÐ· неÑабоÑеÑи компоненÑи в кÑÐ°Ð¹Ð½Ð¸Ñ Ñайл.
ШиÑÑовани Ð¸Ð·Ñ Ð¾Ð´Ð½Ð¸ Ñайлове
ÐаÑиÑениÑе Ñ Ð¿Ð°Ñола изÑ
одни докÑменÑи Ñе оÑваÑÑÑ Ð¿Ð¾ ÑÑÑÐ¸Ñ Ð½Ð°Ñин каÑо неÑиÑÑованиÑе, но Ñ ÐµÐ´Ð½Ð¾ допÑлниÑелно ÑвойÑÑво, коеÑо ÑÑÑбва да Ñе наÑÑÑои пÑÑво. ÐÑиÑвоеÑе паÑолаÑа на PdfSrc.Password пÑеди да пÑомениÑе Active := True, и PDFium Ñе Ñ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° пÑи оÑваÑÑнеÑо:
PdfSrc.Password := 'user-password';
PdfSrc.FileName := 'protected.pdf';
PdfSrc.Active := True;
if not PdfSrc.Active then
raise Exception.Create('Wrong password or file cannot be opened');
PdfDest.ImportPages(PdfSrc, '1-' + IntToStr(PdfSrc.PageCount), InsertAt);
Inc(InsertAt, PdfSrc.PageCount);
PdfSrc.Active := False;
ÐÑеÑна паÑола води до ÑÑÑÐ¸Ñ Ð±ÐµÐ·ÑÑмен ÑезÑлÑÐ°Ñ Active = False, какÑо пÑи липÑÐ²Ð°Ñ Ñайл, Ñака Ñе изÑиÑнаÑа пÑовеÑка е ÑÑÑо Ñолкова необÑ
одима и ÑÑк. ШиÑÑованеÑо не Ñе пÑеÑ
вÑÑÐ»Ñ Ð² кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑменÑ: ÑÑÑаниÑиÑе, импоÑÑиÑани Ð¾Ñ Ð·Ð°ÑиÑен изÑоÑник, Ð¿Ð¾Ð¿Ð°Ð´Ð°Ñ Ð² кÑÐ°Ð¹Ð½Ð¸Ñ Ð´Ð¾ÐºÑÐ¼ÐµÐ½Ñ ÐºÐ°Ñо незаÑиÑено ÑÑдÑÑжание. Ðко обединениÑÑ ÑезÑлÑÐ°Ñ ÑÑÑо изиÑква ÑиÑÑоване, конÑигÑÑиÑайÑе го в PdfDest пÑеди да извикаÑе SaveAs.
Ðапазване на ÑезÑлÑаÑа
SaveAs в TPdf пÑиема или Ñайлов пÑÑ, или TStream. Ðа повеÑеÑо ÑлÑÑаи на обединÑване ÑайловаÑа веÑÑÐ¸Ñ Ð½Ð° меÑода е Ñова, коеÑо ви ÑÑÑбва:
PdfDest.SaveAs('merged-output.pdf');
ÐезадÑлжиÑелниÑÑ Ð²ÑоÑи аÑгÑÐ¼ÐµÐ½Ñ Ðµ TSaveOption, койÑо конÑÑолиÑа Ñежима на запазване. СÑойноÑÑÑа по подÑазбиÑане, saNone, запиÑва инкÑеменÑална акÑÑализаÑиÑ, ако докÑменÑÑÑ Ðµ заÑеден Ð¾Ñ Ñайл, или пÑлно пÑенапиÑване, ако е ÑÑздаден наново. ТÑй каÑо кÑайниÑÑ Ð´Ð¾ÐºÑменÑ, изгÑаден Ñ CreateDocument, винаги е нов, ÑезÑлÑаÑÑÑ Ñе бÑде компакÑен Ñайл Ñ ÐµÐ´Ð½Ð° ÑевизиÑ. ТÑеÑиÑÑ Ð°ÑгÑменÑ, TPdfVersion, ви позволÑва да ÑикÑиÑаÑе веÑÑиÑÑа на PDF заглавиеÑо, когаÑо имаÑе поÑÑебиÑели по веÑигаÑа, коиÑо изиÑÐºÐ²Ð°Ñ ÐºÐ¾Ð½ÐºÑеÑна веÑÑиÑ; оÑÑавÑнеÑо Ð¼Ñ Ð½Ð° pvUnknown позволÑва на PDFium да избеÑе веÑÑиÑÑа вÑз оÑнова на ÑÑдÑÑжаниеÑо.
ÐеÑодиÑе ImportPages и SaveAs, показани ÑÑк, Ñа ÑаÑÑ Ð¾Ñ PDFium VCL Component за Delphi и C++Builder.