如何在Windwos上实现 PDF打印功能?

概述

Foxit PDF SDK 在 Windows 环境下提供了名为 PDFPrintManager 的 PDF 打印管理拓展库,用于实现丰富的 PDF 打印功能。目前,该库支持 C/C++ 和 C# 两种主流开发语言,方便开发者在 Windows 平台上集成 PDF 打印功能。

API 文档与 Demo

  • API 文档目录:位于 foxitpdfsdk_xxx_win\doc\PrintManager 目录下,详细描述了 PDFPrintManager 的各项功能及其 API 使用方法。
  • Demo 目录:位于 foxitpdfsdk_xxx_win\examples\extensions_demo\printmanager 目录下,提供了使用 PDFPrintManager 的示例代码,方便开发者快速上手。

功能特性

PDFPrintManager 提供了以下核心功能:

  1. 获取打印机信息:能够列出系统上已安装的打印机名称及其属性。
  2. 设置打印参数:支持设置打印参数,如纸张大小、打印质量、打印份数等。
  3. 启动与取消打印任务:能够启动打印任务,并在需要时取消正在进行的打印任务。
  4. 获取打印状态:实时获取打印任务的执行状态,如正在打印、打印完成、打印取消等。

其他开发语言使用

对于非 C/C++ 和 C# 的开发语言,开发者可以通过调用 C 接口的方式来实现对 PDFPrintManager 的使用。例如,Java 开发者可以通过 JNI(Java Native Interface)技术来调用 C/C++ 动态链接库(DLL)中的函数。

Java 示例

这里提供一个简单的 Java 示例,用于说明如何通过 JNI 调用 C/C++ 动态链接库中的函数来使用 PDFPrintManager。请注意,具体的实现细节和代码需要根据实际的库函数和 JNI 规则进行编写。

1.下载JNA: Central Repository: net/java/dev/jna/jna (maven.org)

2.在IDEA中导入jna。

2.添加将导入C++接口的java文件:PrintManager_c.java 拷贝到项目里。

代码如下:

import com.sun.jna.Native;
import com.sun.jna.Library;
import com.sun.jna.NativeLong;
import com.sun.jna.Structure;


//import com.sun.jn;
public interface PrintManager_c extends Library  {
    PrintManager_c mydll = (PrintManager_c)Native.load(
            "D:\\下载\\foxitpdfsdk_8_4_1_win\\lib\\fsdk_printmanager_win64.dll",PrintManager_c.class);
    int FXPM_NewPrintManager();
    int FXPM_GetPrintManagerErrorCode(int managerID);
     int FXPM_InitPrintManager(int managerID, String sn, String key);
     void FXPM_ReleasePrintManager(int managerID);
     int FXPM_SetRenderMode(int managerID, int renderMode);

     int FXPM_GetPrinterCount(int managerID);
     String FXPM_GetPrinterName(int managerID, int printerIndex);
     int FXPM_GetPaperSizeCount(int managerID, String printerName);
     int FXPM_GetPaperSizeWidth(int managerID, String printerName, int paperIndex);
     int FXPM_GetPaperSizeHeight(int managerID, String printerName, int paperIndex);
     String FXPM_GetPaperSizeName(int managerID, String printerName, int paperIndex);
     int FXPM_GetPaperSizeID(int managerID, String printerName, int paperIndex);
     int FXPM_GetPaperSourceCount(int managerID, String printerName);
     String FXPM_GetPaperSourceName(int managerID, String printerName, int sourceIndex);
     int FXPM_GetPaperSourceID(int managerID, String printerName, int sourceIndex);
    String FXPM_GetDefaultPrinterName(int managerID);
     int FXPM_GetDefaultPaperSize(int managerID, String printerName);
     int FXPM_GetDefaultPaperSource(int managerID, String printerName);

     int FXPM_PrintPDFFromFile(int managerID, String pdfFileName, String pdfPassword);
    int FXPM_PrintPDFFromMemory(int managerID, String pdfData,int pdfDataLength, String pdfPassword);
     int FXPM_PrintPDFFromFileToPrinter(int managerID, String pdfFileName, String pdfPassword, String printerName);
     int FXPM_PrintPDFFromMemoryToPrinter(int managerID, String pdfData, String pdfDataLength, String pdfPassword, String printerName);

     int FXPM_NewPrintJob(int managerID);
     int FXPM_AddPDFFromFileToJob(int managerID, int jobID, String pdfFileName, String pdfPassword);
     int FXPM_AddPDFFromMemoryToJob(int managerID, int jobID, String pdfData, int pdfDataLength, String pdfPassword);
    int FXPM_BeginPrintJob(int managerID, int jobID);
     int FXPM_CancelPrintJob(int managerID, int jobID);
     int FXPM_GetPrintJobStatus(int managerID, int jobID);
     int FXPM_ClosePrintJob(int managerID, int jobID);

    int FXPM_SetJobCopies(int managerID, int jobID, int newCopies);
     int FXPM_SetJobColor(int managerID, int jobID, int newColorMode);
    int FXPM_SetJobDuplex(int managerID, int jobID, int newDuplex);
     int FXPM_SetJobRotation(int managerID, int jobID, int newRotation);
     int FXPM_SetJobScaling(int managerID, int jobID, int newScaling);
     int FXPM_SetJobCustomScale(int managerID, int jobID, double newCustomScalePercent);
    int FXPM_SetJobPaperSource(int managerID, int jobID, int newPaperSourceID);
     int FXPM_SetJobPaperSize(int managerID, int jobID, int newPaperSizeID);
     int FXPM_SetJobPageList(int managerID, int jobID, int documentIndex, String pageList);
    int FXPM_SetJobPriority(int managerID, int jobID, int newPriority);
     int FXPM_SetJobQuality(int managerID, int jobID, int newQuality);
     int FXPM_SetJobDocumentName(int managerID, int jobID, String newDocumentName);
    int FXPM_SetJobCollate(int managerID, int jobID, int newCollate);
     int FXPM_SetJobPrinter(int managerID, int jobID, String printerName);
     int FXPM_SetJobAutoCenter(int managerID, int jobID, int isAutoCenter);

    int FXPM_GetJobCopies(int managerID, int jobID);
     int FXPM_GetJobColor(int managerID, int jobID);
     int FXPM_GetJobDuplex(int managerID, int jobID);
     int FXPM_GetJobRotation(int managerID, int jobID);
     int FXPM_GetJobScaling(int managerID, int jobID);
    double FXPM_GetJobCustomScale(int managerID, int jobID);
    int FXPM_GetJobPaperSource(int managerID, int jobID);
    int FXPM_GetJobPaperSize(int managerID, int jobID);
     int FXPM_GetJobPageListCount(int managerID, int jobID, int documentIndex);
    int FXPM_GetJobPageListItem(int managerID, int jobID, int documentIndex, int itemIndex);
    int FXPM_GetJobPriority(int managerID, int jobID);
    int FXPM_GetJobQuality(int managerID, int jobID);
    String FXPM_GetJobDocumentName(int managerID, int jobID);
    int FXPM_GetJobCollate(int managerID, int jobID);
    String FXPM_GetJobPrinter(int managerID, int jobID);
   int FXPM_IsJobAutoCenter(int managerID, int jobID);
}

3.如果是x64的环境,请修改PrintManager_c.java中fsdk_printmanager_win64.dll的路径

fsdk_printmanager_win64.dll文件在C++版本的Foxit PDF SDK开发包的lib目录中,请确保对应的fsdk_win64.dll和fsdk_printmanager_win64.dll处于同一目录下

4. 打印PDF,参考test_print.java中的代码。

代码示例如下:

// Copyright (C) 2003-2022, Foxit Software Inc..
// All Rights Reserved.
//
// http://www.foxitsoftware.com
//
// The following code is copyrighted and contains proprietary information and trade secrets of Foxit Software Inc..
// You cannot distribute any part of Foxit PDF SDK to any third party or general public,
// unless there is a separate license agreement with Foxit Software Inc. which explicitly grants you such rights.
//
// This file contains an example to demonstrate how to use Foxit PDF SDK to add various annotations to PDF document.


import java.util.Scanner;

public class test_print {

    public static void main(String[] args)  {
        int error_code = 0;
        {
            String sn = "mjO3ajk6VIdJ60s6Pi9ViGwcI4tmqyJli1QJhohndnYW/GkLQwPglw==";
            String key = "8f3g1cGNvRsNQzeSCxDeIrJDFuSLgX1bp1P6VZjYDPRQhflY5nFaPhBko/RmrHaiVsVe9EpKn0jnzmDeUgXJ5v4Q0fCTn4curgJAxRePQI3whL7DBwkI8o9+dYeMHBhrGEOcHQYb0+Vd7lH7J8izJFUOPE6tEAwubdLQdcy4WF7jNrF3ndOSiNhsr8DvZEID6CswNbC+bDPJCQed8KX1/5/BTcrmtdaqlJO7nhSAe/spbAkULkxjsbs0nNgman05z9HzPn6RKsf/b8TC8+W+1sYP0UX1sKBly2TErn3wxQUGaE8CJak8QoZ90wA1LYwVatYOBVStSKH0QUfmYunFe9/oAWLK4NRBnHpTaJlzy1YRavhgz5pdM+NEaJcv+ptXX0AGzyVcEwBXGPuqPwpcNL+jLqTVSTWcYTxV9gmRUtaPHBntAaWAQH9YnuzM9N6iSN4upya28McRPddB8e8ZHB6c9vtTzO6OnfkLNlUK9EqgibsN2v2eaQ8oUkd9h2rzqYf4UFV2rp3+GPy2p8LuKiLJ8tAt+oKE/J5z13b/tPWlOXrdID9JoQz7zaeoBVGHAfCxNnvmuGiclFmJ6I2Uf6bc8MBPDtX+ZKLOZM3cvo5HJnUcTYEjPba61vQsHk9QsMIJK6TdcHjMrg3w1RyZm3+4LitJBHeW8lPBaq/w2tlYyh/QjXIHYaTf3OoQTVcFw4tKy1+mkPxcYADq/axlqyZ1K7v/E8iiO+D/+O5yAhimEkSpNqSzvN5llgknaJI1yMX74HCjbf0EaNAtm2cP89zIohjdQlJNDoWdpJK3F5qu72Q6qIbq4Yi0H/4BQ9S0rhBA8QhXAMXZPtV3wdzv8Rr5PIbmpNBY5bnEdIcIi8uxSamzjL1/w43Rx8TKsW5/VfB6cwqAujbwvY52XWLayPtlyiIq0xs8jVPfVHdKJXMKX9hu+fad3GZS6NYKWQHWN/DJ2AhnzMFvaM7bY8q7yyERmSg7kSqamw9xPwFdAaR2kwL+1soZ+I+wHLZZ+j2txjMHwDkO1/QVKqRSFqGt7Ya86thSrKWoLdbj//uZpWGS9f2jtNBj7jlH6BhO3/SeJH+H0jXEbbuEhVIYMo/iUv9wYB0AclC2SR7dOR7ValnrGB5D+z9q5Q4F+SZxUAqNxHBTtOqFyz32JlY6fNi7s/a/35YcdQ+Drv/Kp2M+mcKiQ9zpkj+K5tWYQskfg0lVwOwDAvRvLek6bkPGsrXGqRQoR5t93X/NNpTbTij2V7IS7CDbvF5hUIyyN99tlMb4HThJR17hK7S69aVgCV+JgD7XFvnh5P7o/JKJY+7qUIGcNmMZU5D4Aip7PohL52SuK3Z7GZfWP6AZumvcBwj6qFY+pA32gJ28W4z98/ZC+mJntSGV+Fk=";
            int managerID = PrintManager_c.mydll.FXPM_NewPrintManager();
            int initResult = PrintManager_c.mydll.FXPM_InitPrintManager(managerID, sn, key);
            if (initResult == 1) {
                System.out.println("Default printer: " + PrintManager_c.mydll.FXPM_GetDefaultPrinterName(managerID));

                System.out.println("Printer list: ");
                int printerCount = PrintManager_c.mydll.FXPM_GetPrinterCount(managerID);
                for (int printerIndex = 0; printerIndex < printerCount; printerIndex++) {
                    System.out.println(printerIndex + " = " + PrintManager_c.mydll.FXPM_GetPrinterName(managerID, printerIndex));
                }
                int printerChoice = -1;
                String pdf_path="";
                while ((printerChoice < 0) || (printerChoice >= printerCount)) {

                    System.out.println("选择打印机: ");
                    Scanner scan = new Scanner(System.in);
                    String str = scan.next(); 
                    printerChoice = Integer.parseInt(str);
                }

                while (pdf_path =="") {

                    System.out.println("输入文件路径: ");
                    Scanner scan = new Scanner(System.in); 
                    pdf_path = scan.next(); 
                }

                String printerName = PrintManager_c.mydll.FXPM_GetPrinterName(managerID, printerChoice);
                System.out.println("Paper source list: ");
                int paperSourceCount = PrintManager_c.mydll.FXPM_GetPaperSourceCount(managerID, printerName);
                for (int paperSourceIndex = 0; paperSourceIndex < paperSourceCount; paperSourceIndex++) {
                    String paperSourceName = PrintManager_c.mydll.FXPM_GetPaperSourceName(managerID, printerName, paperSourceIndex);
                    int paperSourceID = PrintManager_c.mydll.FXPM_GetPaperSourceID(managerID, printerName, paperSourceIndex);
                    System.out.println(paperSourceIndex + " = " + paperSourceName + " [" + paperSourceID + "]");
                }


                System.out.println("Paper size list: ");
                int paperSizeCount = PrintManager_c.mydll.FXPM_GetPaperSizeCount(managerID, printerName);
                for (int paperSizeIndex = 0; paperSizeIndex < paperSizeCount; paperSizeIndex++) {
                    String paperSizeName = PrintManager_c.mydll.FXPM_GetPaperSizeName(managerID, printerName, paperSizeIndex);
                    int paperSizeID = PrintManager_c.mydll.FXPM_GetPaperSizeID(managerID, printerName, paperSizeIndex);
                    System.out.println(paperSizeIndex + " = " + paperSizeName + " [" + paperSizeID + "]");
                }

                int jobID = PrintManager_c.mydll.FXPM_NewPrintJob(managerID);
                PrintManager_c.mydll.FXPM_SetJobPrinter(managerID, jobID,printerName);
               //设置要打印的文件路径
                PrintManager_c.mydll.FXPM_AddPDFFromFileToJob(managerID, jobID,pdf_path,"");
                       
               /* PrintManager_c.mydll.FXPM_SetJobAutoCenter(managerID,jobID,1);
                // PrintManager_c.mydll.FXPM_SetJobColor(managerID,jobID,2);

                 PrintManager_c.mydll.FXPM_SetJobCollate(managerID,jobID,0);
                 PrintManager_c.mydll.FXPM_SetJobDuplex(managerID,jobID,0);
                 //PrintManager_c.mydll.FXPM_SetJobCustomScale(managerID,jobID,);
                 PrintManager_c.mydll.FXPM_SetJobCopies(managerID,jobID,1);
                 PrintManager_c.mydll.FXPM_SetJobDocumentName(managerID,jobID,"test_doc_name");
                 //PrintManager_c.mydll.FXPM_SetJobPageList();
                 PrintManager_c.mydll.FXPM_SetJobPaperSize(managerID,jobID,0);
                 PrintManager_c.mydll.FXPM_SetJobPaperSource(managerID,jobID,0);
                // PrintManager_c.mydll.FXPM_SetJobPriority(managerID,jobID,);
                 PrintManager_c.mydll.FXPM_SetJobQuality(managerID,jobID,-3);

                */
                PrintManager_c.mydll.FXPM_SetJobRotation(managerID, jobID, 0);
                //  PrintManager_c.mydll.FXPM_SetJobScaling(managerID,jobID,);
                int err_code = PrintManager_c.mydll.FXPM_BeginPrintJob(managerID, jobID);

                int state = PrintManager_c.mydll.FXPM_GetPrintJobStatus(managerID, jobID);
                while (state < 2100) {
                    state = PrintManager_c.mydll.FXPM_GetPrintJobStatus(managerID, jobID);
                }

                PrintManager_c.mydll.FXPM_ReleasePrintManager(managerID);
            }
        }
    }
}

程序运行时需要键入选择打印机和要打印的PDF文件路径。

(纸张尺寸、缩放等可以参考代码里注释掉的那部分参数设置)