Skip to content

lingjinguang/PrintAssistTool

Repository files navigation

IMCISAssistTool项目:(适配于xp系统)

​ 支持webSocket服务浏览器:基于websocket-shap(https://github.com/sta/websocket-sharp)开源项目开发,实现浏览器和客户端通信。

​ ie浏览器:IMCISPrintAssist.dll通过activeX插件形式在ie上使用。

开发工具:Visual Studio 2010

FrameWork版本:.Net FrameWork 4

项目结构图

image-20200827171912673

打印方法封装在IMCISPrintTool程序集中,基于WebSocket的PrinterService服务调用PrintImage/PreView进行打印预览

MainForm.cs:应用的主图形界面。

Program.cs:程序的入口Main方法

Services文件夹:目前只有一个PrintServices.cs(只支持jpg、html、pdf打印)。

Test文件夹:print.html打印测试文件(ws的创建、连接、数据传输)。

Common文件夹:放置一些公共文件。

Model文件夹:放置数据类型的cs文件。

Utils文件夹:工具文件夹,工具属性的方法另外封装起来。

后端搭建WebSocket服务(MainForm.cs)

引用
using WebSocketSharp.Net;
using WebSocketSharp.Server;

private Setting setting = null;
HttpServer httpsv = null;
private void StartService(bool isInit)
{
    try
    {
        if (httpsv != null) httpsv.Stop();
        httpsv = null;

        //默认保存端口
        setting.Port = this.txt_port.Text;
        FileUtils.SaveSetting(setting);

        //监听服务开启
        int post = Convert.ToInt32(this.txt_port.Text);
        httpsv = new HttpServer(post);

        // 添加WebSocket服务
        httpsv.AddWebSocketService<PrinterService>("/PrinterService");

        //开启服务
        httpsv.Start();
    }
    catch (Exception ex)
    {
        
    }
}

前端连接webSocket服务(请参考PrintControl>Test>Print.html 测试用例)

//服务地址“ws://localhost:port/PrinterService” ,port值是启动打印服务时设置的端口值
var ws;
function connectWebSocket(url) {
    //实例化WebSocket对象
    ws = new WebSocket(url);
    //连接成功建立后响应
    ws.onopen = function () {
        log("成功连接到" + url);
    }
    //收到服务器消息后响应
    ws.onmessage = function (event) {
        log("收到服务器消息:"+event.data);
        var ret = JSON.parse(event.data);
        if (ret.code != 0)
            log("异常:" + ret.msg);
        else
            log("打印成功,后续需要回调打印成功接口");
    }
    //连接关闭后响应
    ws.onclose = function () {
        log("关闭连接");
        ws = null;
    }
    return false;
}

//发送信息到webSocket服务器进行通信
function preview (sendData){
    if (!ws || ws.readyState !== 1) {
        alert('请先连接服务');
        return false;
    }
    //发送数据
    ws.send(JSON.stringify(sendData));
}
var sendData = {
    file_type: "pdf",
    print_type: "filePath",
    event_type: "preview",
    direction: $("#Direction").val(),
    printerName: $("#printerNames").val(),
    paperName: $("#paperNames").val(),
    data: $('#temp').val()
};
preview(sendData);

数据类型

var sendData = {
    file_type: "pdf",	//jpg、html、pdf 三种文件类型
    print_type: "filePath",	//filePath、Base64 二种打印数据来源方式类型
    event_type: "print",	//print、preview分别是打印、打印预览
    direction: 1,	//1:纵向;2:横向
    printerName: "",	//打印机名称
    paperName: "",	//打印纸张名称
    width: 210,	//自定义模版宽度
    height: 297,	//自定义模版长度
    customSizeFlag: false,	//是否使用自定义模版 true:是,false:否
    data: data	//data可以是url字符串或者图片转成base64的字符串
};

后端响应前端的send事件(OnMessage)

using WebSocketSharp;
using WebSocketSharp.Server;
using IMCISPrintAssist.Model;
using IMCISPrintAssist.Utils;
using IMCISPrintAssist.Common;

/// <summary>
/// 客户端发送send请求会被触发,接收请求数据
/// </summary>
protected override void OnMessage(MessageEventArgs e)
{
    String result = "打印成功!";
    try
    {
        PrinterData printerData = JsonHelper.DeserializeJsonToObject<PrinterData>(e.Data);
        string eventType = (printerData.eventType).ToUpper();
        string printType = (printerData.printType).ToUpper();
        string folderName = Guid.NewGuid().ToString();  //pdf转图片所存放的文件夹名称
        string tempDir = Path.Combine(Directory.GetCurrentDirectory(), "tempImg");  //生成图片临时存放文件夹
        string tempImageDir = Path.Combine(tempDir, folderName);
        //string targetPath = Path.Combine(tempDir, fileName + ".jpg");
        int width = printerData.width;
        int height = printerData.height;
        Boolean customSizeFlag = printerData.customSizeFlag;
        WebRequest webreq = null;
        WebResponse webres = null;
        Boolean isUrl = HttpUtils.IsUrl(Convert.ToString(printerData.data));
        string fileType = printerData.fileType.ToUpper();
        #region
            if (File.Exists(Convert.ToString(printerData.data)))   //fileType由于IMCIS没有对应变量,data是路径文件名时取值为其后缀,否则当printType时“BASE64”也是JPG,否则就是HTML打印
            {
                fileType = Path.GetExtension(Convert.ToString(printerData.data)).Substring(1).ToUpper();
            }
        else if (isUrl) //网络文件,通过ContentType获取
        {
            webreq = WebRequest.Create(Convert.ToString(printerData.data));
            webres = webreq.GetResponse();
            string[] contentType = Convert.ToString(webres.ContentType).Split('/');
            fileType = contentType.Length > 1 ? contentType[1].ToUpper() : fileType;
        }
        else if (fileType != "PRINTERNAMES" && fileType != "PAGESIZES")
        {
            fileType = printType == "BASE64" ? "JPG" : "HTML";
        }
        #endregion
            switch (fileType)
            {
                case "JPG":
                case "JPEG":
                case "PNG":
                case "RAW":
                case "BMP":
                    if (isUrl)
                    {
                        using (Stream stream = webres.GetResponseStream())
                        {
                            using (Image image = Image.FromStream(stream))
                            {
                                printerData.image = image;
                                result = PrintUtils.PrintImage(printerData);
                            }
                        }
                    }
                    else
                    {
                        if(printType == "FILEPATH")
                        {
                            printerData.filePath = printerData.data;
                        }
                        else if(printType == "BASE64")
                        {
                            printerData.imgBase64 = printerData.data;
                        }
                        result = PrintUtils.PrintImage(printerData);
                    }
                    break;
                case "TXT":
                    PrintUtils.PrintTxt(printerData.data, printType);
                    break;
                case "PDF":
                    string fileName = Path.GetFileNameWithoutExtension(printerData.data);  //通过完整路径取得pdf文件名称作为jpg的文件名
                    if (isUrl)
                    {
                        using (Stream stream = webres.GetResponseStream())
                        {
                            MemoryStream ms = HttpUtils.StreamToMemoryStream(stream);
                            Pdf2JpgUtils.Pdf2Jpg(ms, Path.Combine(tempDir, fileName + ".jpg"), null, folderName);
                        }
                    }
                    else
                    {
                        Pdf2JpgUtils.Pdf2Jpg(Convert.ToString(printerData.data), Path.Combine(tempDir, fileName + ".jpg"), null, folderName);
                    }

                    if (eventType == "PRINT")
                    {
                        var files = Directory.GetFiles(tempImageDir).OrderBy(f => Convert.ToInt32(Path.GetFileNameWithoutExtension(f)));
                        foreach (var file in files)
                        {
                            printerData.filePath = file;
                            result = PrintUtils.PrintImage(printerData);
                        }
                        try
                        {
                            //删除文件夹
                            Directory.Delete(tempImageDir, true);
                        }
                        catch (Exception ex)
                        {
                            result = string.Format("删除临时目录出错:{0};其他错误信息:{1}", tempImageDir, ex);
                        }
                    }
                    else if (eventType == "PREVIEW")
                    {
                        printerData.filePath = tempImageDir;
                        result = PrintUtils.PreView(printerData);
                    }
                    break;
                case "HTML":
                    string tempPdf = Path.Combine(Directory.GetCurrentDirectory(), "tempPdf");
                    string tempPdfDir = Path.Combine(tempPdf, folderName);
                    Directory.CreateDirectory(tempPdfDir);
                    string tempPdfPath = Path.Combine(tempPdfDir, "Html2Pdf.pdf");
                    Html2PdfUtils.Html2Pdf(Convert.ToString(printerData.data).Trim(), tempPdfPath, printerData.paperName, printerData.direction, customSizeFlag, width, height);
                    Pdf2JpgUtils.Pdf2Jpg(tempPdfPath, Path.Combine(tempDir, "Html2Pdf.jpg"), null, folderName);
                    if (eventType == "PRINT")
                    {
                        var files = Directory.GetFiles(tempImageDir).OrderBy(f => Convert.ToInt32(Path.GetFileNameWithoutExtension(f)));
                        foreach (var file in files)
                        {
                            printerData.filePath = file;
                            result = PrintUtils.PrintImage(printerData);
                        }
                        try
                        {
                            //删除临时文件夹
                            Directory.Delete(tempImageDir, true);
                            Directory.Delete(tempPdfDir, true);
                        }
                        catch (Exception ex)
                        {
                            result = string.Format("删除临时目录出错:{0};其他错误信息:{1}", tempPdfDir, ex);
                        }
                    }
                    else if (eventType == "PREVIEW")
                    {
                        printerData.filePath = tempImageDir;
                        result = PrintUtils.PreView(printerData);
                    }
                    break;
                case "PRINTERNAMES":
                    result = PrintUtils.GetPrinterNames();
                    break;
                case "PAGESIZES":
                    result = PrintUtils.GetPageSizesByName(Convert.ToString(printerData.data));
                    break;
                default:
                    result = "参数异常:fileType字段只能为jpg、pdf、html、getPrinterName、getPageSizes";
                    break;
            }
    }
    catch(Exception ex)
    {
        result = "打印出错【" + ex.Message + "";
    }
    Send(result);
}

JPG打印

//使用Drawing进行图片处理
using System.Drawing;
using System.Drawing.Printing;
/// <summary>
/// 打印图片
/// </summary>
public BaseResult PrintImage(string data, string print_type)
{
    try
    {
        var setting = FileUtils.GetSetting();

        if (string.IsNullOrEmpty(setting.Name))
            return BaseResult.Error("请先设置默认打印机");
        if(string.IsNullOrEmpty(data))
            return BaseResult.Error("要打印的数据不存在");

        Image image = print_type == "FILEPATH" ? new Bitmap(data) : Base64ToImg(data);

        PrintDocument pd = new PrintDocument();
        pd.DefaultPageSettings.PrinterSettings.PrinterName = setting.Name;

        pd.PrintPage += (o, e) =>
        {
            PageSettings settings = e.PageSettings;
            var paperHeight = settings.PaperSize.Height;
            var paperWidth = settings.PaperSize.Width;
            //Rectangle m = e.MarginBounds;
            int margin = 10;
            var imgHeight = 0;
            var imgWidth = 0;
            if ((double)image.Width / (double)image.Height > (double)paperWidth / (double)paperHeight) // 图片等比例放大,宽度超出了,先确定宽度
            {
                imgWidth = (int)(paperWidth - margin * 2);
                imgHeight = (int)((double)image.Height * (double)imgWidth / (double)image.Width - margin * 2);
            }
            else
            {
                imgHeight = (int)(paperHeight - margin * 2);
                imgWidth = (int)((double)image.Width / (double)image.Height * imgHeight - margin * 2);
            }
            e.Graphics.DrawImage(image, margin, margin, imgWidth, imgHeight);
        };
        //开始打印
        pd.Print();
        image.Dispose();

        return BaseResult.Success("");
    }
    catch (Exception e)
    {
        return BaseResult.Error(e.Message);
    }
}

PDF打印(PDF转成JPG在通过PrintImage打印)

//PdfiumViewer处理pdf文件转成Image类型数据
//该程序集兼容xp参考 https://github.com/dlynine/katahiromz_pdfium
    
public static void Pdf2Jpg(string sourcePath, string targetPath, int? pages, string folderName)
{
    if (string.IsNullOrEmpty(sourcePath))
        throw new ArgumentNullException("sourcePath");
    if (string.IsNullOrEmpty(targetPath))
        throw new ArgumentNullException("targetPath");
    if (!System.IO.File.Exists(sourcePath))
        throw new Exception("文件不存在:" + sourcePath);
    using (var pdfDocument = PdfiumViewer.PdfDocument.Load(sourcePath))
    {
        Pdf2Jpg(pdfDocument, targetPath, pages, folderName);
    }
}

public static void Pdf2Jpg(PdfiumViewer.PdfDocument pdfDocument, string targetPath, int? pages, string folderName)
{
    if (string.IsNullOrEmpty(targetPath))
        throw new ArgumentNullException("targetPath");

    var dir = Path.GetDirectoryName(targetPath);
    if (!Directory.Exists(dir))
        Directory.CreateDirectory(dir);

    if (pdfDocument.PageCount == 1)
        pages = 1;

    var imageDir = Path.Combine(dir, string.IsNullOrEmpty(folderName) ? Guid.NewGuid().ToString() : folderName);
    Directory.CreateDirectory(imageDir);
    if (pages != null)
    {
        pages--;//PdfiumViewer.PdfDocument的页数是从0开始的
        using (var image = pdfDocument.Render(pages.Value, ConfigDefine.Pdf2JpgResolution, ConfigDefine.Pdf2JpgResolution, PdfiumViewer.PdfRenderFlags.CorrectFromDpi))
        {
            if (ConfigDefine.Pdf2JpgScaleRatio != 0)
            {
                Stream imageStream = new MemoryStream();
                image.Save(imageStream, ImageFormat.Jpeg);
                int imgWidth = Convert.ToInt32(image.Width * ConfigDefine.Pdf2JpgScaleRatio);
                int imgHeight = Convert.ToInt32(image.Height * ConfigDefine.Pdf2JpgScaleRatio);
                using (var imgScaleStream = ImageScale2Stream(imageStream, imgWidth, imgHeight, ""))
                {
                    using (var imgScale = System.Drawing.Image.FromStream(imgScaleStream))
                    {
                        imgScale.Save(Path.Combine(imageDir, folderName + ".jpg"));
                        imgScale.Save(targetPath);
                    }
                }
            }
            else
            {
                image.Save(Path.Combine(imageDir, folderName + ".jpg"));
                image.Save(targetPath);
            }
        }
    }
    else
    {
        for (pages = 0; pages < pdfDocument.PageCount; pages++)
        {
            using (var image = pdfDocument.Render(pages.Value, ConfigDefine.Pdf2JpgResolution, ConfigDefine.Pdf2JpgResolution, PdfiumViewer.PdfRenderFlags.CorrectFromDpi))
            {
                if (ConfigDefine.Pdf2JpgScaleRatio != 0)
                {
                    Stream imageStream = new MemoryStream();
                    image.Save(imageStream, ImageFormat.Jpeg);
                    int imgWidth = Convert.ToInt32(image.Width * ConfigDefine.Pdf2JpgScaleRatio);
                    int imgHeight = Convert.ToInt32(image.Height * ConfigDefine.Pdf2JpgScaleRatio);
                    using (var imgScaleStream = ImageScale2Stream(imageStream, imgWidth, imgHeight, ""))
                    {
                        using (var imgScale = System.Drawing.Image.FromStream(imgScaleStream))
                        {
                            imgScale.Save(Path.Combine(imageDir, pages + ".jpg"));
                        }
                    }
                }
                else
                {
                    image.Save(Path.Combine(imageDir, pages + ".jpg"));
                }

            }
        }
    }
}

HTML打印(HTML转PDF转图片打印)

//iTextSharp将HTML转成PDF,PDF再由Pdf2Jpg方法(PdfiumViewer)转成Image数据类型
//PdfiumViewer并不完整,需要把pdfium.dll放在程序安装/运行的根目录
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.IO;
using System.Text;
using iTextSharp.tool.xml;

namespace PrintControl.Utils
{
    public static class Html2PdfUtils // : System.Web.UI.Page
    {
        public static void Html2Pdf(string htmlText, string tempPdfPath)
        {
            if (string.IsNullOrEmpty(htmlText))
                throw new Exception("传入的html无内容:" + htmlText);
            MemoryStream outputStream = new MemoryStream();//要把PDF写到哪个串流
            byte[] data = Encoding.UTF8.GetBytes(htmlText);//字串转成byte[]
            MemoryStream msInput = new MemoryStream(data);
            Document doc = new Document();//要写PDF的文件,建构子没填的话预设直式A4
            PdfWriter writer = PdfWriter.GetInstance(doc, outputStream);
            //指定文件预设开档时的缩放为100%
            PdfDestination pdfDest = new PdfDestination(PdfDestination.XYZ, 0, doc.PageSize.Height, 1f);
            //开启Document文件 
            doc.Open();

            //使用XMLWorkerHelper把Html parse到PDF档里
            XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8, new UnicodeFontFactory());
            //XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msInput, null, Encoding.UTF8,字体);

            //将pdfDest设定的资料写到PDF档
            PdfAction action = PdfAction.GotoLocalPage(1, pdfDest, writer);
            writer.SetOpenAction(action);
            doc.Close();
            msInput.Close();
            outputStream.Close();
            //回传PDF档案 
            var bytes = outputStream.ToArray();

            var ret = Convert.ToBase64String(bytes);
            try
            {
                string strbase64 = ret;
                strbase64 = strbase64.Replace(' ', '+');
                System.IO.MemoryStream stream = new System.IO.MemoryStream(Convert.FromBase64String(strbase64));
                System.IO.FileStream fs = new System.IO.FileStream(tempPdfPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
                byte[] b = stream.ToArray();
                //byte[] b = stream.GetBuffer();
                fs.Write(b, 0, b.Length);
                fs.Close();

            }
            catch (Exception ex)
            {

            }
        }
    }
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published