欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#调用Python脚本打印pdf文件

程序员文章站 2022-07-11 08:35:15
介绍:通过pdf地址先将文件下载到本地,然后调用打印机打印,最后将下载的文件删除。 环境:windows系统。(windows64位) windows系统中安装python3.6.2环境 资料: O2S.Components.PDFRender4NET.dll(vs项目引用,这是在C#中调用打印机) ......

 介绍:通过pdf地址先将文件下载到本地,然后调用打印机打印,最后将下载的文件删除。

  环境:windows系统。(windows64位)

     windows系统中安装python3.6.2环境

   资料:

    o2s.components.pdfrender4net.dll(vs项目引用,这是在c#中调用打印机)

    

    在python环境中添加:pywin32-221.win-amd64-py3.6 和  gsprint文件(python环境中执行文件下载 打印 删除)

 

windows环境下安装python环境:

C#调用Python脚本打印pdf文件

点击程序进行安装........

推荐安装教程:

 配置打印环境:

  首先进入cmd环境导入requests模块

C#调用Python脚本打印pdf文件

 

  下载pywin32 官网 

   C#调用Python脚本打印pdf文件

找准对应版本.....

C#调用Python脚本打印pdf文件

 

或者是我提供的下载地址(我的是3.6.2python版本)

C#调用Python脚本打印pdf文件

接下来就是安装了.....

C#调用Python脚本打印pdf文件

 C#调用Python脚本打印pdf文件

C#调用Python脚本打印pdf文件

C#调用Python脚本打印pdf文件

C#调用Python脚本打印pdf文件

 

然后在python环境中去测试一下

C#调用Python脚本打印pdf文件

解压

C#调用Python脚本打印pdf文件

将gsprint文件夹与上面win32的安装模块文件放在一起,如下:

C#调用Python脚本打印pdf文件

 

 后面文件中对应地址:

C#调用Python脚本打印pdf文件

 

首先从c#代码开始

   界面预览:这个很简单,在wpf中可以写个button按钮事件即可

C#调用Python脚本打印pdf文件

 

我直接贴出打印的核心代码:

 /* 由于质保书后台接口给的是pdf下载地址,所以我的思路是 先下载到本地然后打印,打印完成后在删除文件
                     * 由于时间仓促:文件的下载及删除功能使用python来完成(这里也可以改为c#来写)
                     * 
                     */
                    try
                    {
                        // 1:文件下载 
                        var result = pythonhelper.pdfdownload(this.model.zhibaoshu.downloadurl);
                        if (!result.successed)
                        {
                            dispatcher.invoke(() =>
                            {
                                messagebox.show("pdf质保书下载失败,请联系管理员", "打印消息", messageboxbutton.ok, messageboximage.stop);
                                loghelper.loginfo($"文件:【{this.model.zhibaoshu.downloadurl}】下载失败\r\n 错误:\r\n{result.message}");
                                // 发生错误返回主页
                                utilhelper.backtomain(this, mainpage.stpbg, () => { backtomain(); }, null);
                            });
                        }
                        thread.sleep(1000);
                        _savepath = result.result.tostring();
                        // 2:打印下载pdf文件(python打印只能打印一份,还有打印样式未完善,所以还是用c#来调用打印)
                        result = pythonhelper.pdfprint(_savepath, model.zhibaoshu.printername);
                       // result = ph.pdfprint(_savepath, model.zhibaoshu.printername, (short)model.zhibaoshu.printnum);
                        if (!result.successed)
                        {
                            dispatcher.invoke(() =>
                            {
                                messagebox.show("pdf质保书打印失败,请联系管理员", "打印消息", messageboxbutton.ok, messageboximage.stop);
                                loghelper.loginfo($"文件:【{result.result.tostring()}】打印失败\r\n 错误:\r\n{result.message}");
                                // 发生错误返回主页
                                utilhelper.backtomain(this, mainpage.stpbg, () => { backtomain(); }, null);
                            });
                        }
                        thread.sleep(1000);
                        //// 3:删除pdf文件 
                        //result = pythonhelper.pdfdelete(_savepath);
                        //if (!result.successed)
                        //{
                        //    //messagebox.show("pdf质保书删除失败", "打印消息", messageboxbutton.ok, messageboximage.stop);
                        //    loghelper.loginfo($"文件:【{this.model.zhibaoshu.downloadurl}】删除失败\r\n 错误:\r\n{result.message}");
                        //    // 发生错误返回主页
                        //    //utilhelper.backtomain(this, mainpage.stpbg, () => { backtomain(); }, null);
                        //    // 文件删除失败不代表打印失败,所以这里结果重置一下
                        //    result.successed = true;
                        //}

                    }
                    catch (exception e)
                    {

 
                    }

 

pythonhelper.cs 文件 (代码未优化)

    /// <summary>
    /// 执行python文件
    /// </summary>
    public static class pythonhelper
    {
        /// <summary>
        /// 程序debug目录文件路径 
        /// </summary>
        private static string _binpath = system.appdomain.currentdomain.setupinformation.applicationbase;

        /// <summary>
        /// 保存本地pdf文件名 
        /// </summary>
        private static string _pdfname = datetime.now.tostring("hhmmss") + ".pdf";

        /// <summary>
        /// 文件下载保存本地地址+文件名 
        /// </summary>
        private static string _savepath = _binpath + "file\\" + _pdfname;

        /// <summary>
        /// pdf下载
        /// </summary>
        /// <param name="downloadurl">pdf下载地址</param>
        /// <returns>返回保存文件地址</returns>
        public static handlingresult pdfdownload(string downloadurl)
        {
            // python文件地址 ,待处理python文件的路径,本例中放在debug文件夹下
            string _pdfdownloadpy = _binpath + "python\\pdfdownload.py";
            var result = new handlingresult() { successed = false };
            try
            {
                // 拼接执行命令(方法传参)
                arraylist arraylist = new arraylist();
                arraylist.add(downloadurl);
                arraylist.add(_savepath);
                foreach (var param in arraylist)//添加参数 
                    _pdfdownloadpy += " " + param;

                // 执行设置
                processstartinfo start = new processstartinfo();
                start.filename = "python";//执行python.exe
                                          //执行python脚本的命令
                start.arguments = _pdfdownloadpy;
                //设置运行python脚本的初始目录 这里注意:如果你的python脚本有文件操作,必须设置初始目录,python脚本所在的目录
                start.workingdirectory = _binpath + "python\\";
                start.useshellexecute = false;
                start.createnowindow = true;
                start.redirectstandardoutput = true;
                start.redirectstandarderror = true;
                using (process process = process.start(start))
                {
                    // 异步获取命令行内容
                    process.beginoutputreadline();
                    // 为异步获取订阅事件
                    process.outputdatareceived += new datareceivedeventhandler((sender, e) =>
                    {
                        // 打印python脚本中的信息
                        loghelper.loginfo(e.data);
                        //messagebox.show(e.data);//e.data 就是命令行打印的最后一行信息
                    });
                }
                result.successed = true;
                result.result = _savepath;
            }
            catch (exception e)
            {
                result.successed = false;
                result.message = e.message;
                loghelper.logerror(e);

            }

            return result;
        }

        /// <summary>
        /// 删除pdf文件
        /// </summary>
        /// <param name="path">本地pdf文件全路径</param>
        public static handlingresult pdfdelete(string path)
        {
            string _pdfdeletepy = _binpath + "python\\pdfdelete.py";
            var result = new handlingresult() { successed = true };
            try
            {
                // 拼接执行命令(方法传参)
                arraylist arraylist = new arraylist();
                arraylist.add(path);
                foreach (var param in arraylist)//添加参数 
                    _pdfdeletepy += " " + param;

                // 执行设置
                processstartinfo start = new processstartinfo();
                start.filename = "python";//执行python.exe
                                          //执行python脚本的命令
                start.arguments = _pdfdeletepy;
                //设置运行python脚本的初始目录 这里注意:如果你的python脚本有文件操作,必须设置初始目录,python脚本所在的目录
                start.workingdirectory = _binpath + "python\\";
                start.useshellexecute = false;
                start.createnowindow = true;
                start.redirectstandardoutput = true;
                start.redirectstandarderror = true;
                using (process process = process.start(start))
                {

                    // 异步获取命令行内容
                    process.beginoutputreadline();
                    // 为异步获取订阅事件
                    process.outputdatareceived += new datareceivedeventhandler((sender, e) =>
                    {
                        // 打印python脚本中的信息
                        loghelper.loginfo(e.data);
                        //messagebox.show(e.data);//e.data 就是命令行打印的最后一行信息
                    });
                }

            }
            catch (exception e)
            {
                result.successed = false;
                result.message = e.message;
            }
            return result;
        }

        /// <summary>
        /// 打印pdf
        /// </summary>
        /// <param name="printpath">文件全路径</param>
        /// <param name="printname">打印机名称</param>
        public static handlingresult pdfprint(string printpath, string printname)
        {
            string _pdfprint = _binpath + "python\\pdfprint.py";
            var result = new handlingresult() { successed = true };
            try
            {
                // 拼接执行命令(方法传参)
                arraylist arraylist = new arraylist();
                arraylist.add(printpath);
                arraylist.add(printname);
                foreach (var param in arraylist)//添加参数 
                    _pdfprint += " " + param;

                // 执行设置
                processstartinfo start = new processstartinfo();
                start.filename = "python";//执行python.exe 
                start.arguments = _pdfprint;//执行python脚本的命令
                //设置运行python脚本的初始目录 这里注意:如果你的python脚本有文件操作,必须设置初始目录,python脚本所在的目录
                start.workingdirectory = _binpath + "python\\";
                start.useshellexecute = false;
                start.createnowindow = true;
                start.redirectstandardoutput = true;
                start.redirectstandarderror = true;
                using (process process = process.start(start))
                {
                    // 异步获取命令行内容
                    process.beginoutputreadline();
                    // 为异步获取订阅事件
                    process.outputdatareceived += new datareceivedeventhandler((sender, e) =>
                    {
                        // 打印python脚本中的信息
                        loghelper.loginfo(e.data);
                        //messagebox.show(e.data);//e.data 就是命令行打印的最后一行信息
                    });
                }
            }
            catch (exception e)
            {
                loghelper.logerror(e);
                result.successed = false;
                result.message = e.message;
            }
            return result;
        }

    }

 

第二种调用打印机方法:使用第三方o2s.components.pdfrender4net.dll文件调用打印机打印pdf

        /// <summary>
        /// 打印pdf文件
        /// </summary>
        /// <param name="pdfpath">文件全路径</param>
        /// <param name="printname">打印机名称</param>
        /// <param name="copies">打印份数</param>
        /// <returns></returns>
        public handlingresult pdfprint(string pdfpath, string printname, short copies = 1)
        {
            pdffile file =null;
            var result = new handlingresult()
            {
                successed = true,
            };
            try
            {
                file = pdffile.open(pdfpath);
                printersettings settings = new printersettings();
                system.drawing.printing.printdocument pd = new system.drawing.printing.printdocument();
                settings.printername = printname; // "npi84ffaf (hp laserjet mfp m436)"; // 打印机名称
                settings.printtofile = false;

                //设置纸张大小(可以不设置,取默认设置)3.90 in,  8.65 in
                papersize ps = new papersize("test", 4, 9);
                ps.rawkind = 9; //如果是自定义纸张,就要大于118,(a4值为9,详细纸张类型与值的对照请看http://msdn.microsoft.com/zh-tw/library/system.drawing.printing.papersize.rawkind(v=vs.85).aspx)
                o2s.components.pdfrender4net.printing.pdfprintsettings pdfprintsettings =
                    new o2s.components.pdfrender4net.printing.pdfprintsettings(settings);
                pdfprintsettings.papersize = ps;
                pdfprintsettings.pagescaling =
                    o2s.components.pdfrender4net.printing.pagescaling.fittoprintermarginsproportional;
                pdfprintsettings.printersettings.copies = copies;

                file.print(pdfprintsettings);
            }
            catch (exception e)
            {
                loghelper.logerror(e);
                result.successed = false;
                result.message = e.message;
            }
            finally
            {
                file.dispose();
                loghelper.loginfo($"{pdfpath}---打印成功");
            }

            return result;
        }

  

以上是c#部分代码,以下python脚本就比较简单了。

注:其实可以只写一个打印方法即可,为了流程看到清楚,所以一个操作一个方法文件。

C#调用Python脚本打印pdf文件

 

1:根据地址下载pdf文件 pdfdownload.py

# -*- coding: utf-8 -*-

# 声明字符编码
# coding:utf-8
import os, sys
from requests import get
def dwnloadpfd(file_path, save_path):
    '''
    根据file_path地址下载文件保存到save_path路径中
    :param file_path:下载地址
    :param save_path: 保存地址
    :return:true或false
    '''
    try:
        head = {
            "user-agent": "mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/53.0.2785.89 safari/537.36"
        }
        response =get(file_path, headers=head).content
        with open(save_path, 'wb') as f:
            f.write(response)
        print('%s--下载成功'%(save_path))
        return save_path
    except exception as e:
        print(e)
        return none

if __name__ == "__main__":
    #url = ""
    #dwnloadpfd(url, "musics/1.pdf")
    # 接收参数
    dwnloadpfd(sys.argv[1], sys.argv[2])

  

 2:打印pdf文件:pdfprint.py

# -*- coding: utf-8 -*-

# 声明字符编码
# coding:utf-8
import os,sys 
import win32api
import win32print 
ghostscript_path = "c:\\program files\\gs\\gs9.27\\bin\\gswin64.exe"
gsprint_path = "c:\\program files\\gsprint\\gsprint.exe"


def pdfprint(full_file_name, print_name=win32print.getdefaultprinter()):
    '''
    根据指定的打印机打印pdf文件
    :param full_file_name:文件全路径
    :param print_name:打印机名称(默认打印机)
    :return:
    ''' 
    try:
        win32api.shellexecute(
            0,
            'open',
            gsprint_path,
            '-ghostscript "' + ghostscript_path + '" -printer "' + print_name + '" "' + full_file_name + '"',
            '.',
            0
        )
        print('%s---打印成功' % (full_file_name))
    except exception as e:
        print('%s---打印异常:\n' % (full_file_name))
        print(str(e)) 
if __name__ == "__main__": 
    # path = "e:\\开发项目\\学习项目\\python\\musicdownload\\musics\\1.pdf"
    # name = win32print.getdefaultprinter()  # "npi84ffaf (hp laserjet mfp m436)" #
    # pdfprint(path, name)
    len(sys.argv) 
    print(sys.argv[1]) # 文件路径
    print(sys.argv[2:])# 打印机名称
    name = ' '.join(sys.argv[2:])
    print(name)
    # 打印机名称中有可能有空格 
    pdfprint(sys.argv[1], name)
         

 

  

 3:打印完成后即可删除文件 pdfdelete.py

# -*- coding: utf-8 -*-

# 声明字符编码
# coding:utf-8
import os, sys
def pdfdelete(full_path):
    '''
    根据文件全路径地址删除
    :param full_path:文件路径
    :return:true或false
    '''
    try:
        if (os.path.exists(full_path)):
            os.remove(full_path)
            print(full_path + '---删除成功')
            return true
        else:
            print(full_path + '---删除文件不存在')
            return false
    except exception as e:
        print(str(e))
        return false

if __name__ == "__main__":
    pdfdelete(sys.argv[1])

  

 注:上面python调用打印机进行打印出来的效果需要调整及打印的份数这些设置后续有待完善。