Att dela upp en stor PDF i mindre filer är avgörande för dokumentdistribution, arkivering och bearbetning. Den Dela PDF demo visar hur man delar upp PDF-dokument med olika metoder med PDFium VCL i Delphi.
Översikt
Denna omfattande demo erbjuder tre uppdelningslägen: individuella sidor, sidintervall och efter bokmärken. Det inkluderar förloppsspårning, detaljerad loggning och anpassningsbar utdatafilnamn.
Delade lägen
- Enskilda sidor – Skapa en separat PDF för varje sida
- Sidintervall – Dela upp efter anpassade sidintervall (t.ex. 1-5, 6-10)
- Efter bokmärken – Dela vid bokmärkesgränser för logiska sektioner
PDFium DLL-krav
Innan du kör ett PDFium VCL-program, se till att PDFium DLL-filerna är installerade:
pdfium32.dll/pdfium64.dll– Standardversioner (~5-6 MB)pdfium32v8.dll/pdfium64v8.dll– Med V8 JavaScript-motor (~23-27 MB)
Installation: Kör PDFiumVCL\DLLs\CopyDlls.bat som administratör för att automatiskt kopiera DLL:erna till Windows systemkataloger.
Delas upp i enskilda sidor
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
procedure TFormMain.ProcessIndividualPages; var I: Integer; OutputFile: string; OutputDir: string; PdfNew: TPdf; begin OutputDir := GetOutputDirectory; UpdateProgress('Splitting into individual pages...', 0, Pdf.PageCount); PdfNew := TPdf.Create(nil); try for I := 1 to Pdf.PageCount do begin if FCancelled then Break; // Create new document for this page PdfNew.CreateDocument; // Import single page PdfNew.ImportPages(Pdf, IntToStr(I), 1); // Generate output filename OutputFile := GenerateOutputFileName( edtFilePattern.Text, Pdf.FileName, I); OutputFile := OutputDir + '\' + OutputFile; // Save the single-page PDF if PdfNew.SaveAs(OutputFile) then begin LogMessage(Format('Created: %s', [ExtractFileName(OutputFile)])); Inc(FSplitCount); end else LogMessage(Format('Failed to create: %s', [OutputFile]), LOG_ERROR); PdfNew.Active := False; UpdateProgress('Processing...', I, Pdf.PageCount); end; finally PdfNew.Free; end; end; |
Dela upp efter sidintervall
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
procedure TFormMain.ProcessPageRanges; var Ranges: TPageRanges; I: Integer; OutputFile: string; OutputDir: string; PageList: string; PdfNew: TPdf; begin Ranges := ParsePageRanges(edtPageRanges.Text); if Length(Ranges) = 0 then begin LogMessage('No valid page ranges specified', LOG_ERROR); Exit; end; OutputDir := GetOutputDirectory; UpdateProgress('Splitting by page ranges...', 0, Length(Ranges)); PdfNew := TPdf.Create(nil); try for I := 0 to High(Ranges) do begin if FCancelled then Break; PdfNew.CreateDocument; // Build page range string PageList := Format('%d-%d', [Ranges[I].StartPage, Ranges[I].EndPage]); // Import the range PdfNew.ImportPages(Pdf, PageList, 1); // Generate output filename OutputFile := Format('%s\%s_pages_%d-%d.pdf', [ OutputDir, ChangeFileExt(ExtractFileName(Pdf.FileName), ''), Ranges[I].StartPage, Ranges[I].EndPage ]); if PdfNew.SaveAs(OutputFile) then begin LogMessage(Format('Created: %s (pages %s)', [ExtractFileName(OutputFile), PageList])); Inc(FSplitCount); end; PdfNew.Active := False; UpdateProgress('Processing...', I + 1, Length(Ranges)); end; finally PdfNew.Free; end; end; |
Parsar sidintervall
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
function TFormMain.ParsePageRanges(const RangeStr: string): TPageRanges; var Parts: TStringList; I: Integer; Part: string; DashPos: Integer; StartPage, EndPage: Integer; Range: TPageRange; begin SetLength(Result, 0); if Trim(RangeStr) = '' then Exit; Parts := TStringList.Create; try Parts.Delimiter := ','; Parts.DelimitedText := RangeStr; for I := 0 to Parts.Count - 1 do begin Part := Trim(Parts[I]); if Part = '' then Continue; DashPos := Pos('-', Part); if DashPos > 0 then begin // Range: "1-5" StartPage := StrToIntDef(Trim(Copy(Part, 1, DashPos - 1)), 0); EndPage := StrToIntDef(Trim(Copy(Part, DashPos + 1, Length(Part))), 0); end else begin // Single page: "3" StartPage := StrToIntDef(Part, 0); EndPage := StartPage; end; if (StartPage > 0) and (EndPage >= StartPage) and (EndPage <= Pdf.PageCount) then begin Range.StartPage := StartPage; Range.EndPage := EndPage; SetLength(Result, Length(Result) + 1); Result[High(Result)] := Range; end; end; finally Parts.Free; end; end; |
Uppdelning efter bokmärken
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
procedure TFormMain.ProcessBookmarks; var Bookmarks: TBookmarks; I: Integer; StartPage, EndPage: Integer; OutputFile: string; OutputDir: string; BookmarkTitle: string; PdfNew: TPdf; begin Bookmarks := Pdf.Bookmarks; if Length(Bookmarks) = 0 then begin LogMessage('No bookmarks found in document', LOG_WARNING); Exit; end; OutputDir := GetOutputDirectory; UpdateProgress('Splitting by bookmarks...', 0, Length(Bookmarks)); PdfNew := TPdf.Create(nil); try for I := 0 to High(Bookmarks) do begin if FCancelled then Break; StartPage := Bookmarks[I].PageNumber; // End page is start of next bookmark or end of document if I < High(Bookmarks) then EndPage := Bookmarks[I + 1].PageNumber - 1 else EndPage := Pdf.PageCount; if (StartPage > 0) and (EndPage >= StartPage) then begin PdfNew.CreateDocument; PdfNew.ImportPages(Pdf, Format('%d-%d', [StartPage, EndPage]), 1); // Clean bookmark title for filename BookmarkTitle := Bookmarks[I].Title; BookmarkTitle := StringReplace(BookmarkTitle, '/', '_', [rfReplaceAll]); BookmarkTitle := StringReplace(BookmarkTitle, '\', '_', [rfReplaceAll]); BookmarkTitle := StringReplace(BookmarkTitle, ':', '_', [rfReplaceAll]); OutputFile := Format('%s\%02d_%s.pdf', [ OutputDir, I + 1, BookmarkTitle]); if PdfNew.SaveAs(OutputFile) then begin LogMessage(Format('Created: %s (pages %d-%d)', [ExtractFileName(OutputFile), StartPage, EndPage])); Inc(FSplitCount); end; PdfNew.Active := False; end; UpdateProgress('Processing...', I + 1, Length(Bookmarks)); end; finally PdfNew.Free; end; end; |
Anpassningsbara utdatafilnamn
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function TFormMain.GenerateOutputFileName( const Pattern, SourceFile: string; PageNum: Integer): string; var BaseName, Ext: string; begin BaseName := ChangeFileExt(ExtractFileName(SourceFile), ''); Ext := ExtractFileExt(SourceFile); Result := StringReplace(Pattern, '{filename}', BaseName, [rfReplaceAll, rfIgnoreCase]); Result := StringReplace(Result, '{page}', IntToStr(PageNum), [rfReplaceAll, rfIgnoreCase]); Result := StringReplace(Result, '{page:000}', Format('%.3d', [PageNum]), [rfReplaceAll, rfIgnoreCase]); // Ensure .pdf extension if not EndsText('.pdf', Result) then Result := Result + '.pdf'; end; |
Framsteg och statusuppdateringar
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
procedure TFormMain.UpdateProgress(const Status: string; Current, Total: Integer); begin lblStatus.Caption := Status; if Total > 0 then begin prgProgress.Max := Total; prgProgress.Position := Current; lblProgress.Caption := Format('%d of %d pages', [Current, Total]); end else begin prgProgress.Position := 0; lblProgress.Caption := 'Initializing...'; end; Application.ProcessMessages; end; procedure TFormMain.LogMessage(const Msg: string; const Level: string = 'INFO'); var TimeStamp, LogLine: string; begin TimeStamp := FormatDateTime('hh:nn:ss', Now); LogLine := Format('[%s] %s: %s', [TimeStamp, Level, Msg]); mmoLog.Lines.Add(LogLine); mmoLog.Perform(WM_VSCROLL, SB_BOTTOM, 0); Application.ProcessMessages; end; |
Avbokningsstöd
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure TFormMain.btnCancelClick(Sender: TObject); begin FCancelled := True; LogMessage('Cancellation requested...', LOG_WARNING); end; procedure TFormMain.SetProcessingState(Processing: Boolean); begin FProcessing := Processing; btnBrowse.Enabled := not Processing; edtPdfFile.Enabled := not Processing; grpOptions.Enabled := not Processing; btnSplit.Enabled := not Processing; btnCancel.Enabled := Processing; end; |
Sammanfattning av slutförande
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TFormMain.ShowCompletionSummary; var ElapsedTime: TDateTime; ElapsedStr: string; begin ElapsedTime := Now - FStartTime; ElapsedStr := FormatDateTime('nn:ss', ElapsedTime); if FCancelled then LogMessage(Format('Operation cancelled. Created %d files in %s', [FSplitCount, ElapsedStr]), LOG_WARNING) else LogMessage(Format('Split completed. Created %d files in %s', [FSplitCount, ElapsedStr]), LOG_SUCCESS); end; |
Användningsfall
- Extrahera kapitel – Dela böcker eller manualer efter kapitel med hjälp av bokmärken
- Distribuera sidor – Ge olika teammedlemmar olika sidintervall
- Arkiv efter sektion – Organisera stora dokument i mindre, hanterbara filer
- Sidextraktion – Extrahera specifika sidor för att dela eller granska
Slutsats
Demon Split PDF demonstrerar flexibiliteten hos PDFium VCL för dokumentmanipulation. Oavsett om du delar upp efter sidor, intervall eller logiska avsnitt definierade av bokmärken, är processen enkel och effektiv.
I kombination med anpassningsbara utdatanamn och förloppsspårning kan du bygga professionella dokumentdelningsverktyg för alla arbetsflöden.
Ladda ner PDFium VCL-komponent från loslab.com och ta kontroll över dina PDF-dokument.