将 PDF 文件拆分为多个文件 - Java -LEADTOOLS SDK 23.0

本教程展示了使用 LEADTOOLS SDK 在 Java 应用程序中单独保存多页 PDF 的每一页的三种不同技术。

概述 
概括本教程介绍如何在 Java 控制台应用程序中拆分多页 PDF 文件。
完成时间30分钟
Eclipse 项目下载教程项目 (3 KB)
平台Java 应用程序
集成开发环境
开发许可证下载 LEADTOOLS
尝试使用其他语言

所需知识

在开始将PDF 文件拆分为多个文件 - Java教程之前,请先查看添加引用和设置许可证教程,熟悉创建项目的基本步骤。

创建项目并添加 LEADTOOLS 引用

从“添加引用”和“设置许可证”教程中创建的项目副本开始。如果该项目不可用,请按照该教程中的步骤创建它。

所需的引用取决于项目的目的。可以通过.jar位于 的本地文件添加引用<INSTALL_DIR>\LEADTOOLS23\Bin\Java

对于该项目,需要以下参考文献:

  • leadtools.annotations.engine.jar
  • leadtools.caching.jar
  • leadtools.codecs.jar
  • leadtools.document.converter.jar
  • leadtools.document.jar
  • leadtools.document.pdf.jar
  • leadtools.document.writer.jar
  • leadtools.imageprocessing.core.jar
  • leadtools.jar
  • leadtools.ocr.jar
  • leadtools.pdf.jar
  • leadtools.svg.jar

本教程使用 LEADTOOLS 编解码器库支持。有关您的应用程序所需 JAR 文件的完整列表,请参阅Java 应用程序所需包含的文件

设置许可证文件

许可证用于解锁项目所需的功能。必须在调用任何工具包函数之前设置许可证。有关详细信息(包括不同平台的教程),请参阅设置运行时许可证

运行时许可证有两种类型:

  • 评估许可证,在下载评估工具包时获得。它允许对工具包进行评估。
  • 部署许可证。如果需要部署许可证文件和开发者密钥,请参阅获取许可证

注意:在添加引用和设置许可证教程中更详细地介绍了添加 LEADTOOLS 引用和设置许可证

添加分页代码

创建项目、添加参考并设置许可证后,就可以开始编码了。

在项目资源管理器Main.java中打开该类。将以下语句添加到顶部的块中。import

Java
import java.io.IOException; 
import java.nio.file.*; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
 
import leadtools.*; 
import leadtools.codecs.*; 
import leadtools.pdf.*; 
import leadtools.document.*; 
import leadtools.document.converter.*; 
import leadtools.document.writer.*; 
import leadtools.ocr.*; 

将下面的代码添加到run()创建分割文件目录的方法中,并调用下面部分中创建的方法。

Java
private void run(String[] args) { 
   try { 
      Platform.setLibPath("C:\\LEADTOOLS23\\Bin\\CDLL\\x64"); 
      Platform.loadLibrary(LTLibrary.LEADTOOLS); 
      Platform.loadLibrary(LTLibrary.CODECS); 
      Platform.loadLibrary(LTLibrary.DOCUMENT_WRITER); 
      Platform.loadLibrary(LTLibrary.PDF); 
      Platform.loadLibrary(LTLibrary.OCR); 
          
      SetLicense(); 
          
      String multipageFile = "C:\\LEADTOOLS23\\Resources\\Images\\leadtools.pdf"; 
      String _splitDir = "C:\\LEADTOOLS23\\Resources\\Images\\Split PDFs"; 
      if(!Files.exists(Paths.get(_splitDir))) 
         Files.createDirectory(Paths.get(_splitDir)); 
      splitUsingRasterCodecs(multipageFile, _splitDir); 
      splitUsingPDFFile(multipageFile, _splitDir); 
      splitUsingLEADDocument(multipageFile, _splitDir);         
   } catch (Exception ex) { 
      System.err.println(ex.getMessage()); 
      ex.printStackTrace(); 
   } 
} 

下面将讨论三种不同的 PDF 文件页面分割技术,每种技术都有其自身的优势。

方法 1:使用 RasterCodecs

在这种方法中,每个页面都以光栅(位图)图像的形式加载,然后保存为光栅 PDF 文件。这是使用 RasterCodecs 类完成的。

这种方法的主要优点是代码简单。只需几行代码,而且相同的代码可以用于其他多页格式,例如 TIFF 或 GIF。

_Main在名为 的类中创建一个名为 的新方法splitUsingRasterCodecs(String inputFile, String _directory)。此方法将在方法内部调用run(),如上所示。

Java
void splitUsingRasterCodecs(String inputFile, String _directory) { 
   RasterCodecs codecs = new RasterCodecs(); 
   codecs.getOptions().getPdf().setInitialPath("C:\\LEADTOOLS23\\Bin\\CDLL\\x64"); 
   int totalPages = codecs.getTotalPages(inputFile); 
   System.out.println("SplitUsingRasterCodecs..\nTotal pages:" + totalPages + " Splitting pages:"); 
       
   for (int page = 1; page <= totalPages; page++) { 
      System.out.println(page + ".."); 
      String outputFilename = Paths.get(inputFile).toFile().getName(); 
      if(outputFilename.lastIndexOf('.') != -1) 
         outputFilename = outputFilename.substring(0, outputFilename.lastIndexOf('.')); 
      outputFilename = outputFilename + "_codecs_page" + page + ".pdf"; 
      String outputFile = _directory + "\\" + outputFilename; 
      RasterImage image = codecs.load(inputFile, page); 
      codecs.save(image, outputFile, RasterImageFormat.RAS_PDF_LZW, 0); 
      image.dispose(); 
   } 
   codecs.dispose(); 
} 

方法 2:使用 PDFFile

这种方法使用了PDFFile类,它是 PDF 格式的专用类。这意味着该代码不能用于其他文档或图像格式。

这种方法的主要优点在于它保留了 PDF 页面的内容,因为它不会将可搜索的文本转换为光栅图像。此外,在许多情况下,它不会导致原始 PDF 文件中的图像重新编码,从而提高性能并保持图像质量。代码也非常简单。

_Main在名为 的类中创建一个名为 的新方法splitUsingPDFFile(String inputFile, String _directory)。此方法将在方法内部调用run(),如上所示。

Java
void splitUsingPDFFile(String inputFile, String _directory) { 
   PDFFile pdfFile = new PDFFile(inputFile); 
   int totalPages = pdfFile.getPageCount(); 
   System.out.println("SplitUsingPDFFile..\nTotal pages:" + totalPages + " Splitting pages:"); 
   for (int page = 1; page <= totalPages; page++) { 
      System.out.println(page + ".."); 
      String outputFilename = Paths.get(inputFile).toFile().getName(); 
      if(outputFilename.lastIndexOf('.') != -1) 
         outputFilename = outputFilename.substring(0, outputFilename.lastIndexOf('.')); 
      outputFilename = outputFilename + "_pdffile_page" + page + ".pdf"; 
      String outputFile = _directory + "\\" + outputFilename; 
      pdfFile.extractPages(page, page, outputFile); 
   } 
} 

方法 3:使用 LEADDocument

这种方法是三种方法中最先进的,它利用了LEADDocumentDocumentConverter类。

由于这些类适用于多种格式,因此可以使用类似的代码来拆分多种类型的文档文件并输出为不同的文档和光栅格式。例如,在下面的代码中,只需将其更改DocumentFormat.PDFDocumentFormat.DOCX即可将文件拆分为 Microsoft Word 输出页面,而不是 PDF 页面。此外,这些功能强大的类还可以生成优化的输出文件。

配置执行器服务

ExecutorService由于文档转换作业是异步的,因此需要配置Java并将其分配给该类RasterDefaults

在类中定义一个ExecutorService字段_Main,并在中添加以下代码run()

Java
private ExecutorService service; 
   private void run(String[] args) { 
      try { 
         Platform.setLibPath("C:\\LEADTOOLS23\\Bin\\CDLL\\x64"); 
         Platform.loadLibrary(LTLibrary.LEADTOOLS); 
         Platform.loadLibrary(LTLibrary.CODECS); 
         Platform.loadLibrary(LTLibrary.DOCUMENT_WRITER); 
         Platform.loadLibrary(LTLibrary.PDF); 
         Platform.loadLibrary(LTLibrary.OCR); 
          
         SetLicense(); 
          
         // Set ExecutorService in RasterDefaults for Document Converter Jobs 
         service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 
         RasterDefaults.setExecutorService(service); 
          
         String multipageFile = "C:\\LEADTOOLS23\\Resources\\Images\\leadtools.pdf"; 
         String _splitDir = "C:\\LEADTOOLS23\\Resources\\Images\\Split PDFs"; 
         if(!Files.exists(Paths.get(_splitDir))) 
            Files.createDirectory(Paths.get(_splitDir)); 
         splitUsingRasterCodecs(multipageFile, _splitDir); 
         splitUsingPDFFile(multipageFile, _splitDir); 
         splitUsingLEADDocument(multipageFile, _splitDir);         
      }  
      catch(Exception ex) { 
         System.err.println(ex.getMessage()); 
         ex.printStackTrace(); 
      } 
   } 

DocumentConvertor代码

_Main在名为 的类中创建一个名为 的新方法splitUsingLEADDocument(string inputFile, string _directory)。此方法将在方法内部调用run(),如上所示。

Java
void splitUsingLEADDocument(String inputFile, String _directory) { 
   DocumentWriter documentWriter = new DocumentWriter(); 
   // Optional: use documentWriter.getOptions() and documentWriter.setOptions() to modify PDF options  
   var createOptions = new CreateDocumentOptions(); 
       
   LEADDocument inputDocument = DocumentFactory.loadFromFile(inputFile, new LoadDocumentOptions()); 
   OcrEngine ocrEngine = OcrEngineManager.createEngine(OcrEngineType.LEAD); 
   ocrEngine.startup(null, null, null, "C:\\LEADTOOLS23\\Bin\\Common\\OcrLEADRuntime"); 
   System.out.println("SplitUsingLEADDocument..\nTotal pages:" + inputDocument.getPages().getOriginalPageCount() + " Splitting pages:"); 
   for(var inputPage : inputDocument.getPages()) { 
      LEADDocument pageDocument = DocumentFactory.create(createOptions); 
      pageDocument.setAutoDisposeDocuments(true); 
      pageDocument.setName("VirtualPage"); 
      pageDocument.getPages().add(inputPage); 
      DocumentConverter docConverter = new DocumentConverter(); 
      docConverter.setDocumentWriterInstance(documentWriter); 
      int page = inputDocument.getPages().indexOf(inputPage) + 1; // (+ 1) since index is zero-based 
      System.out.println(page + ".."); 
      var jobData = new DocumentConverterJobData(); 
      jobData.setDocument(inputPage); 
      String outputFilename = Paths.get(inputFile).toFile().getName(); 
      if(outputFilename.lastIndexOf('.') != -1) 
         outputFilename = outputFilename.substring(0, outputFilename.lastIndexOf('.')); 
      outputFilename = outputFilename + "_LeadDoc_page" + page + ".pdf"; 
      String outputFile = _directory + "\\" + outputFilename; 
      jobData.setOutputDocumentFileName(outputFile); 
      jobData.setDocumentFormat(DocumentFormat.PDF); 
      var job = docConverter.getJobs().createJob(jobData); 
      docConverter.getJobs().runJob(job); 
   } 
   System.out.println(); 
   ocrEngine.shutdown(); 
} 

处理流

要使用 I/O 流处理文件,请import在顶部的块中添加一个语句来导入java.io.InputStream对象。

Java
import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.*; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
 
import leadtools.*; 
import leadtools.codecs.*; 
import leadtools.pdf.*; 
import leadtools.document.*; 
import leadtools.document.converter.*; 
import leadtools.document.writer.*; 
import leadtools.ocr.*; 

将方法中的现有代码替换run()为以下内容:

Java
 private void run(String[] args) { 
        try { 
            Platform.setLibPath("C:\\LEADTOOLS23\\Bin\\CDLL\\x64"); 
            Platform.loadLibrary(LTLibrary.LEADTOOLS); 
            Platform.loadLibrary(LTLibrary.CODECS); 
            Platform.loadLibrary(LTLibrary.DOCUMENT_WRITER); 
            Platform.loadLibrary(LTLibrary.PDF); 
            Platform.loadLibrary(LTLibrary.OCR); 
 
            SetLicense(); 
 
            // Set ExecutorService in RasterDefaults for Document Converter Jobs 
            service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 
            RasterDefaults.setExecutorService(service); 
 
            String multipageFile = "C:\\LEADTOOLS23\\Resources\\Images\\leadtools.pdf"; 
            InputStream multipageInputStream = Files.newInputStream(Paths.get(multipageFile)); 
            LeadDynamicStream multipageLeadDynamicStream = new LeadDynamicStream(multipageInputStream, false); 
            splitUsingRasterCodecs(multipageLeadDynamicStream); 
            splitUsingLEADDocument(multipageLeadDynamicStream); 
 
        } catch (Exception ex) { 
            System.err.println(ex.getMessage()); 
            ex.printStackTrace(); 
        } 
    } 

添加splitUsingRasterCodecs处理ILeadStream对象的方法重载。

Java
void splitUsingRasterCodecs(ILeadStream inputStream) { 
   RasterCodecs codecs = new RasterCodecs(); 
   codecs.getOptions().getPdf().setInitialPath("C:\\LEADTOOLS23\\Bin\\CDLL\\x64"); 
   int totalPages = codecs.getTotalPages(inputStream); 
   System.out.println("SplitUsingRasterCodecs..\nTotal pages:" + totalPages + " Splitting pages:"); 
 
   for (int page = 1; page <= 5; page++) { 
      System.out.println(page + ".."); 
      RasterImage image = codecs.load(inputStream, page); 
      LeadDynamicStream leadDynamicStream = new LeadDynamicStream(); 
      codecs.save(image, leadDynamicStream, RasterImageFormat.RAS_PDF_LZW, 0); 
      // Use output Stream containing the split file before it is closed and freed for the next page 
      leadDynamicStream.close(); 
      leadDynamicStream.dispose(); 
      image.dispose(); 
   } 
   System.out.println(); 
   codecs.dispose(); 
} 

添加splitUsingLEADDocument处理ILeadStream对象的方法重载。

Java
void splitUsingLEADDocument(ILeadStream inputStream) { 
    DocumentWriter documentWriter = new DocumentWriter(); 
    // Optional: use documentWriter.getOptions() and documentWriter.setOptions() to modify PDF options 
    var createOptions = new CreateDocumentOptions(); 
 
    LEADDocument inputDocument = DocumentFactory.loadFromStream(inputStream, new LoadDocumentOptions()); 
    OcrEngine ocrEngine = OcrEngineManager.createEngine(OcrEngineType.LEAD); 
    ocrEngine.startup(null, null, null, "C:\\LEADTOOLS23\\Bin\\Common\\OcrLEADRuntime"); 
    System.out.println("SplitUsingLEADDocument..\nTotal pages:" + inputDocument.getPages().getOriginalPageCount() 
            + " Splitting pages:"); 
    for (var inputPage : inputDocument.getPages()) { 
        LEADDocument pageDocument = DocumentFactory.create(createOptions); 
        pageDocument.setAutoDisposeDocuments(true); 
        pageDocument.setName("VirtualPage"); 
        pageDocument.getPages().add(inputPage); 
        DocumentConverter docConverter = new DocumentConverter(); 
        docConverter.setDocumentWriterInstance(documentWriter); 
        int page = inputDocument.getPages().indexOf(inputPage) + 1; // (+ 1) since index is zero-based 
        System.out.println(page + ".."); 
        var jobData = new DocumentConverterJobData(); 
        jobData.setDocument(pageDocument); 
        jobData.setOutputDocumentStream(new LeadDynamicStream()); 
        jobData.setDocumentFormat(DocumentFormat.PDF); 
        jobData.setJobName("LeadDoc_page" + page); 
        var job = docConverter.getJobs().createJob(jobData); 
        Jobs_JobCompleted jobsCompleted = new Jobs_JobCompleted(); 
        docConverter.getJobs().addJobCompletedListener(jobsCompleted); 
        docConverter.getJobs().runJob(job); 
    } 
} 

添加Jobs_JobCompleted事件监听器类,该类将处理来自上述文档转换器的异步作业,以访问输出文档流。

Java
class Jobs_JobCompleted implements DocumentConverterJobEventListener { 
    public void onEvent(DocumentConverterJobEvent e) { 
        if (e.getOperation() == DocumentConverterJobOperation.COMPLETED) { 
            LeadDynamicStream outputDocumentStream = (LeadDynamicStream) e.getJob().getJobData().getOutputDocumentStream(); 
            // Use Output Document Stream containing the split file before it is closed and freed for the next page 
            outputDocumentStream.close(); 
            outputDocumentStream.dispose(); 
        } 
    } 
} 

运行项目

通过按Ctrl + F11或选择Run -> Run来运行项目。

如果正确执行了这些步骤,应用程序就会运行并创建新文件。每页leadtools.pdf都会以三种不同的方式创建为单独的 PDF 文件,并在文件名称后附加页码。

本教程展示了如何添加必要的引用以加载 PDF 文件的所有页面,并使用各种技术将它们拆分为单独的文档。

参见

更多推荐