跨平台桌面完全体
經過一點點的業余加班努力,終于實現了客戶端跨平臺完全體。客戶端可以調用打印,調用打印預覽,調用打印生成PDF,調用Excel導出。windows下可以驅動模板設計器等。除了攝像頭調用部分和監聽程序接口部分全部實現。攝像頭和監聽接口目前還涉及不到linux運行。普通用戶正常使用的功能是完事了。主要難度在打印預覽實現上。
老winform預覽,是打開winform界面做展示預覽的,預覽邏輯還不少,完全要做界面和服務分離。
//如果是預覽if (printFlag == "PrintPreviewOld" || printFlag == "PrintPreview"){PrintPreview.Document = pdDocument;PrintPreview.ShowPrinterSettingsBeforePrint = false;PrintPreview.ShowPrinterSettingsButton = true;PrintPreview.ShowPageSettingsButton = true;PrintPreview.PrintPreviewControl.Zoom = 1;PrintPreview.WindowState = FormWindowState.Maximized;PrintPreview.ShowDialog();//確定打印if (PrintPreview.printDialogResult == DialogResult.Yes){PrinterSettings setting = pdDocument.PrinterSettings;pdDocument = new PrintDocument();pdDocument.PrinterSettings = setting;iRow = 0;startPage = 0;//訂閱BeginPrint事件 pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);//定義打印內容pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);//訂閱EndPrint事件,釋放資源 pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);//打印PrintProxy();string state = GetPrintState();if (state != ""){if (shouldShowErr){FrmInfo frminfo = new FrmInfo();frminfo.Info = "打印機處于錯誤狀態";frminfo.CoderInfo = state;frminfo.ShowDialog();WriteLog(state);}else{errInfo += state;WriteLog(errInfo);}return;}}//確定打印else if (PrintPreview.printDialogResult == DialogResult.OK){//pdDocument = new PrintDocument();iRow = 0;startPage = 0;int curPage = 0;//當前頁開始int preStart = 0;pintPoints.Clear();//循環繪制每行數據for (int i = iRow; i < namesTable.Rows.Count; i++){if (PrintPreview.CurPage >= 0){if (curPage == PrintPreview.CurPage + 1){break;}}//取出當前行數據DataRow dr = namesTable.Rows[i];//打印類型string PrintType = dr["PrintType"].ToString();//換頁if (PrintType == "PAGE" || (i == (namesTable.Rows.Count - 1))){if (curPage < PrintPreview.CurPage){iRow = i + 1;}else{endRow = i + 1;}curPage++;//打印奇數頁if (PrintPreview.CurPage == -1){if (curPage % 2 != 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}else{pintPoints.Add(new Point(preStart, i));}}}//打印偶數頁else if (PrintPreview.CurPage == -2){if (curPage % 2 == 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}else{pintPoints.Add(new Point(preStart, i));}}}//打印偶數頁逆序else if (PrintPreview.CurPage == -3){if (curPage % 2 == 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Insert(0, new Point(preStart, i));}}else{pintPoints.Insert(0, new Point(preStart, i));}}}//范圍打印else if (PrintPreview.CurPage == -4){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}//當前頁開始位置preStart = i + 1;}}//訂閱BeginPrint事件 pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);//定義打印內容pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);//訂閱EndPrint事件,釋放資源 pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);//打印PrintProxy();string state = GetPrintState();if (state != ""){if (shouldShowErr){FrmInfo frminfo = new FrmInfo();frminfo.Info = "打印機處于錯誤狀態";frminfo.CoderInfo = state;frminfo.ShowDialog();WriteLog(state);}else{errInfo += state;WriteLog(errInfo);}return;}}}先抽取界面數據共性,用來在UI和服務傳輸數據,需要展示預覽界面時候服務端給UI發消息,UI展示界面,把用戶選擇組裝消息發回給服務端。在用戶確認之前服務端處于線程等待狀態。
/// <summary>/// 打印預覽返回實體/// </summary>public class PrintPreViewRetDto{/// <summary>/// 選擇結果/// </summary>public string printDialogResult{get;set;}/// <summary>/// 當前頁/// </summary>public int CurPage{get;set;}/// <summary>/// 范圍開始/// </summary>public int RangeStart{get;set;}/// <summary>/// 范圍結束/// </summary>public int RangeEnd{get;set;}}對接UI層實現,打印抽象接口
/// <summary>/// 操作打印的接口外殼/// </summary>public interface IOperPrintShell{/// <summary>/// 顯示運用程序信息/// </summary>/// <param name="info"></param>/// <param name="coderInfo"></param>void ShowAppInfo(string info, string coderInfo);/// <summary>/// 顯示彈窗消息/// </summary>/// <param name="info"></param>/// <param name="title"></param>void ShowMsgInfo(string info,string title="");/// <summary>/// 保存文件對話框/// </summary>/// <param name="Filter"></param>/// <returns></returns>string SaveFileDialog(string Filter);/// <summary>/// 選擇文件夾對話框/// </summary>/// <param name="Title"></param>/// <returns></returns>string SaveDirDialog(string Title);/// <summary>/// 顯示打印預覽/// </summary>/// <param name="imageJsonName">圖片Base64串JSON文件</param>/// <returns></returns>PrintPreViewRetDto ShowPrintPreview(string imageJsonName);}打印界面接口實現
using DHCLabtrakReportPrint; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace LISClientMsgDeal {/// <summary>/// 操作打印的殼/// </summary>public class OperPrintShell : DHCLabtrakReportPrint.IOperPrintShell{/// <summary>/// 顯示消息框/// </summary>/// <param name="title">標題</param>/// <param name="msg">消息</param>/// <param name="buttonNames">按鈕名稱</param>/// <returns></returns>public string ShowMsgDialog(string title, string msg, string buttonNames){if (MessageServer.UIOper != null){return MessageServer.UIOper.ShowMsgDialog(title, msg, buttonNames);}Console.WriteLine(title+":"+ msg);return "0";}/// <summary>/// 從多個文件選一個彈窗/// </summary>/// <param name="selectStr">用|分割的多個名稱</param>/// <returns></returns>public string SelectFileDialog(string selectStr){if (MessageServer.UIOper != null){return MessageServer.UIOper.ShowSelectTmpFileDialog(selectStr);}Console.WriteLine("沒有UI,默認選擇第一個:");string path = selectStr.Split('|')[0];return path;}/// <summary>/// 保存文件對話框/// </summary>/// <param name="Filter"></param>/// <returns></returns>public string SaveFileDialog(string Filter){if(MessageServer.UIOper != null){return MessageServer.UIOper.ShowSaveFileDialog("保存文件","", Filter);}Console.WriteLine("請輸入要保存的路徑:");string path = Console.ReadLine();return path;}/// <summary>/// 顯示App信息/// </summary>/// <param name="info"></param>/// <param name="coderInfo"></param>public void ShowAppInfo(string info, string coderInfo){string head = DateTime.Now.ToString("hh:mm:ss") + "#";Console.WriteLine(head + info);Console.WriteLine(head + coderInfo);}/// <summary>/// 顯示消息/// </summary>/// <param name="info"></param>/// <param name="title"></param>public void ShowMsgInfo(string info, string title = ""){if (MessageServer.UIOper != null){MessageServer.UIOper.ShowMsgDialog(title, info, "確定");}string head = DateTime.Now.ToString("hh:mm:ss") + "#" + title;Console.WriteLine(head + info);}/// <summary>/// 選擇文件夾對話框/// </summary>/// <param name="Title"></param>/// <returns></returns>public string SaveDirDialog(string Title){if (MessageServer.UIOper != null){return MessageServer.UIOper.ShowSaveDirDialog("選擇要保存的路徑","");}Console.WriteLine("請輸入要保存的路徑:");string path = Console.ReadLine();return path;}/// <summary>/// 顯示打印預覽/// </summary>/// <param name="imageJsonName">圖片Base64串JSON文件</param>/// <returns></returns>public PrintPreViewRetDto ShowPrintPreview(string imageJsonName){if (MessageServer.UIOper != null){return MessageServer.UIOper.ShowPrintPreview(imageJsonName);}string head = DateTime.Now.ToString("hh:mm:ss") + "#" + imageJsonName;Console.WriteLine(head);PrintPreViewRetDto ret = new PrintPreViewRetDto();ret.printDialogResult = "Yes";ret.CurPage = 0;ret.RangeStart = -1;ret.RangeEnd = -1;return ret;}} }和electron的UI交互層
using DHCLabtrakReportPrint; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace LISClientMsgDeal {public class UIOperElectron : IUIOperInterface{/// <summary>/// 連接,通過該連接和UI通信/// </summary>public LIS.IWebSocketConnection Socket{get;set;}/// <summary>/// 消息ID/// </summary>private static int id = 0;/// <summary>/// 顯示消息框/// </summary>/// <param name="title">標題</param>/// <param name="msg">消息</param>/// <param name="buttonNames">按鈕名稱</param>/// <returns></returns>public string ShowMsgDialog(string title,string msg,string buttonNames){if(buttonNames==""){buttonNames = "確定|取消";}UIMsgDto dto = new UIMsgDto();dto.Type = "MsgDialog";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(title);dto.Paras.Add(msg);dto.Paras.Add(buttonNames);//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if (ret != null){if (ret.RetParas != null && ret.RetParas.Count > 0){return ret.RetParas[0];}}return "";}/// <summary>/// 顯示選擇文件對話框/// </summary>/// <param name="selectStr"></param>/// <returns></returns>public string ShowSelectTmpFileDialog(string selectStr){UIMsgDto dto = new UIMsgDto();dto.Type = "SelectTmpFileDialog";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(selectStr);//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if (ret != null){if (ret.RetParas != null && ret.RetParas.Count > 0){return ret.RetParas[0];}}return "";}/// <summary>/// 顯示保存文件對話框/// </summary>/// <param name="title">對話框標題</param>/// <param name="defaultPath">默認路徑</param>/// <param name="filter">篩選:"Image Files (*.jpg;*.png)|*.jpg;*.png"</param>/// <returns>沒選擇就返回空,選擇了就返回路徑</returns>public string ShowSaveFileDialog(string title, string defaultPath, string filter){UIMsgDto dto = new UIMsgDto();dto.Type = "SaveFileDialog";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(title);dto.Paras.Add(defaultPath);dto.Paras.Add(filter);//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if(ret!=null){if(ret.RetParas!=null&& ret.RetParas.Count>0){return ret.RetParas[0];}}return "";}/// <summary>/// 顯示選擇文件夾對話框/// </summary>/// <param name="title">對話框標題</param>/// <param name="defaultPath">默認路徑</param>/// <returns>沒選擇就返回空,選擇了就返回路徑</returns>public string ShowSaveDirDialog(string title, string defaultPath){UIMsgDto dto = new UIMsgDto();dto.Type = "SaveDirDialog";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(title);dto.Paras.Add(defaultPath);//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if (ret != null){if (ret.RetParas != null && ret.RetParas.Count > 0){return ret.RetParas[0];}}return "";}/// <summary>/// 顯示打印預覽/// </summary>/// <param name="imageJsonName">圖片Base64串JSON文件</param>/// <returns></returns>public PrintPreViewRetDto ShowPrintPreview(string imageJsonName){UIMsgDto dto = new UIMsgDto();dto.Type = "PrintPreView";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(imageJsonName);PrintPreViewRetDto retDto = new PrintPreViewRetDto();//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if (ret != null){if (ret.RetParas != null && ret.RetParas.Count > 0){retDto.printDialogResult = ret.RetParas[0];retDto.CurPage = Convert.ToInt32(ret.RetParas[1]);if(ret.RetParas[2]!=""){retDto.RangeStart = Convert.ToInt32(ret.RetParas[2]);}if(ret.RetParas[3]!=""){retDto.RangeEnd = Convert.ToInt32(ret.RetParas[3]);}return retDto;}}retDto.printDialogResult = "Yes";retDto.CurPage = 0;retDto.RangeStart = -1;retDto.RangeEnd = -1;return retDto;}/// <summary>/// 發送消息并且等待返回值/// </summary>/// <param name="dto">消息實體</param>/// <returns>返回結果</returns>private UIMsgDto SenMsgAndWait(UIMsgDto dto){dto.MsgID = id.ToString();id++;string msgStr = JsonConvert.SerializeObject(dto);if(Socket!=null){Socket.Send(msgStr);if(dto.NeedRet==true){//注冊等待UIMessageDeal.WaitReg(Socket.ConnectionInfo.Id.ToString(), dto);int waiteNum = 0;while (true){UIMsgDto ret=UIMessageDeal.GetUIMsgRet(dto.MsgID);if(ret!=null){return ret;}else{System.Threading.Thread.Sleep(200);}waiteNum++;if(waiteNum>40000){break;}}}}return null;}} }界面electron對接層JS,處理服務發來的界面展示消息
//處理服務端后臺的消息 function DealMsgServer(data) {//保存文件對話框if (data.Type == "SaveFileDialog") {var filters = [];if (data.Paras[2] != "") {var arr = data.Paras[2].split('|');for (var i = 0; i < arr.length; i += 2) {var one = { name: arr[i], extensions: [arr[i + 1].split(".")[1]] };filters.push(one);}}dialog.showSaveDialog({title: data.Paras[0],defaultPath: data.Paras[1],filters: filters}).then(result => {data.RetParas = [];data.RetParas.push(result.filePath);console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}).catch(err => {console.log(err)});}//選擇路徑對話框else if (data.Type == "SaveDirDialog") {dialog.showOpenDialog(mainWindow, {properties: ['openDirectory']}).then(result => {data.RetParas = result.filePaths;console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}).catch(err => {console.log(err)});}//選擇模板文件對話框,多選一else if (data.Type == "SelectTmpFileDialog") {var path = data.Paras[0];var pathArr = path.split('|');var buttons = [];for (var i = 0; i < pathArr.length; i++) {var oneArr = pathArr[i].split("/");buttons.push(oneArr[oneArr.length-1]);}var choice = dialog.showMessageBoxSync(mainWindow, {type: "info",buttons: buttons,title: "選擇模板對話框",message: "請選擇要使用的導出模板",defaultId: -1,cancelId: -1});//執行菜單邏輯if (choice >= 0) {data.RetParas = [];data.RetParas.push(pathArr[choice]);console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}else {data.RetParas = [];data.RetParas.push("");console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}}//選擇模板文件對話框,多選一else if (data.Type == "MsgDialog") {var title = data.Paras[0];var msg = data.Paras[1];var buttonStr = data.Paras[2];var nameArr = buttonStr.split('|');var buttons = [];for (var i = 0; i < nameArr.length; i++) {buttons.push(nameArr[i]);}var choice = dialog.showMessageBoxSync(mainWindow, {type: "info",buttons: buttons,title: title,message: msg,defaultId: -1,cancelId: -1});data.RetParas = [];data.RetParas.push(choice);console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}//打印預覽對話框else if (data.Type == "PrintPreView") {var JSONPath = data.Paras[0];//創建新的窗口var printViewWindow = new BrowserWindow({skipTaskbar: false,icon: __dirname + dirSplit + 'lis.ico',webPreferences: {nodeIntegration: true,contextIsolation: false}});//最大化printViewWindow.maximize();printViewWindow.loadFile('main/form/frmPrintView.html', { search: "Json=" + "http://127.0.0.1:8085/UI/" + JSONPath +"&MsgID="+data.MsgID });} }主進程打開預覽界面后接收渲染進程消息
//接收渲染進程消息ipcMain.on('printview', (event, msgData) => {console.log(msgData);if (msgData.Type == "PrintPreView") {console.log("UI->S", "uimsg#" + JSON.stringify(msgData));ws.send("uimsg#" + JSON.stringify(msgData));}});預覽界面,把用戶選擇通過消息發送給主進程,主進程再發送給服務端的websockt讓服務端接著執行邏輯
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><title>打印預覽</title><script type="text/javascript">const ipcRenderer = require('electron').ipcRenderer;window.nodeRequire = require;delete window.require;delete window.exports;delete window.module;</script><script src="../../resource/common/js/lis-commonHISUI.js" type="text/javascript"></script><style type="text/css">.ar {text-align: right;padding-right: 8px;}.ar6 {text-align: right;padding-right: 6px;}.al {text-align: left;padding-right: 10px;}.sp {display: inline-block;width: 15px;}.sp4 {display: inline-block;width: 4px;}.sp6 {display: inline-block;width: 6px;}.sp10 {display: inline-block;width: 10px;}.sp20 {display: inline-block;width: 20px;}</style><script type="text/javascript">//得到傳入的Json路徑var Json = requestUrlParam(location.href, "Json").replace("#", "");var MsgID = requestUrlParam(location.href, "MsgID").replace("#", "");//document.write('<script type="text/javascript" href="' + Json + '"/>');var Align = requestUrlParam(location.href, "Align").replace("#", "");$(function () {if (Align == "Left") {$("#divOper").css("margin", "0 0 0 0");$("#divMian").css("margin", "0 0 0 0");}var CurPage = 0;var printDialogResult = "";var RangeStart = "";var RangeEnd = "";//默認第一頁$("#txtCurPage").val("1");//打印當前頁$("#btnPrintCur").click(function () {printDialogResult = "Ok";SendMsg();});//打印全部$("#btnPrintAll").click(function () {printDialogResult = "Yes";SendMsg();});//關閉$("#btnClose").click(function () {printDialogResult = "Cancel";});//打印奇數頁$("#btnPrintOdd").click(function () {printDialogResult = "OK";CurPage = -1;SendMsg();});//打印偶數頁$("#btnPrintEven").click(function () {printDialogResult = "OK";CurPage = -2;SendMsg();});//偶逆序$("#btnPrintEvenRevert").click(function () {printDialogResult = "OK";CurPage = -3;SendMsg();});//范圍打印$("#btnPrintRange").click(function () {printDialogResult = "OK";RangeStart = $("#txtRangeStart").val();RangeEnd = $("#txtRangeEnd").val();SendMsg();});//上一頁$("#btnPrev").click(function () {CurPage--;if (CurPage < 0) {CurPage = 0;}$("#txtCurPage").val(CurPage+1);DrawPage();});//下一頁$("#btnNext").click(function () {CurPage++;if (CurPage == MaxPageIndex) {CurPage = MaxPageIndex - 1;}$("#txtCurPage").val(CurPage+1);DrawPage();});if (Json == "") {$("#spPage").html("沒按要求傳入Json!");return;}var imgStr = '';$.ajax({type: "get",dataType: "json", //text, json, xmlcache: false, //async: false, //為true時,異步,不等待后臺返回值,為false時強制等待;-asirurl: Json,success: function (imageArr) {for (var i = 0; i < imageArr.length; i++) {if (i > 0) {imgStr += '<div style="font-weight:bold;color:#ff5252;">第' + (i + 1) + '頁</div><img src="' + "data:image/png;base64," + imageArr[i] + '" alt="報告" style="margin-bottom:10px;"/>';}else {imgStr += '<img src="' + "data:image/png;base64," + imageArr[i] + '" alt="報告" style="margin-bottom:10px;"/>';}}$("#spPage").html("當前報告共(" + imageArr.length + ")頁");$("#divMian").html(imgStr);}});//組裝消息function SendMsg() {var msg = {};msg.CurPage = CurPage;msg.printDialogResult = printDialogResult;msg.RangeStart = RangeStart;msg.RangeEnd = RangeEnd;msg.MsgID = MsgID;msg.Type = "PrintPreView";msg.NeedRet = true;msg.Paras = "";msg.RetParas = [printDialogResult, CurPage, RangeStart, RangeEnd];ipcRenderer.send('printview', msg);window.close();}//繪制當前頁function DrawPage() {$("#divMian").html('<img src="' + "data:image/png;base64," + imageArr[CurPage] + '" alt="報告" style="margin-bottom:10px;"/>');}});</script> </head> <body><div id="divOper" style="margin:auto auto;width: 100%;background-color:#F5F5F5; text-align: center; padding: 5px;"><a id="btnPrintCur" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">打印當前頁</a><a id="btnPrintAll" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">打印全部</a><a id="btnClose" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">關閉</a><a id="btnPrintOdd" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">打印奇數頁</a><a id="btnPrintEven" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">打印偶數頁</a><a id="btnPrintEvenRevert" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">偶逆序</a><input id="txtRangeStart" type="text" style="width:30px" class="hisui-validatebox" />-<input id="txtRangeEnd" type="text" style="width:30px" class="hisui-validatebox" /><a id="btnPrintRange" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">范圍打印</a><span id="spPage" style="font-weight: bold; color: #ff5252; font-size: 14px;"></span><input id="txtCurPage" type="text" style="width:30px" class="hisui-validatebox" /><a id="btnPrev" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">上一頁</a><a id="btnNext" href="#" class="hisui-linkbutton" data-options="iconCls:'icon-print',plain:true" style="margin-left:10px;">下一頁</a><span style="font-weight: bold; color: #AAAAAA; font-size: 14px;float:right;margin-right:10px;">打印預覽</span></div><div id="divMian" style="margin: auto auto; width: 850px; background-color: #DDDDDD; text-align: center; padding-top: 10px;"></div> </body> </html>原來winform打印預覽代碼調整,原來的打印預覽彈窗改為PrintPreViewRetDto PrintPreview = Shell.ShowPrintPreview(jsonFile);驅動electron的ui。
//如果是預覽if (printFlag == "PrintPreviewOld" || printFlag == "PrintPreview"){//得到打印預覽的圖片JSONstring jsonFile=GetImageJsonFile();//顯示打印預覽PrintPreViewRetDto PrintPreview = Shell.ShowPrintPreview(jsonFile);//確定打印if (PrintPreview.printDialogResult == "Yes"){PrinterSettings setting = pdDocument.PrinterSettings;pdDocument = new PrintDocument();pdDocument.PrinterSettings = setting;iRow = 0;startPage = 0;//訂閱BeginPrint事件 pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);//定義打印內容pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);//訂閱EndPrint事件,釋放資源 pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);//打印PrintProxy();}//確定打印else if (PrintPreview.printDialogResult == "Ok"){//pdDocument = new PrintDocument();iRow = 0;startPage = 0;int curPage = 0;//當前頁開始int preStart = 0;pintPoints.Clear();//循環繪制每行數據for (int i = iRow; i < namesTable.Rows.Count; i++){if (PrintPreview.CurPage >= 0){if (curPage == PrintPreview.CurPage + 1){break;}}//取出當前行數據DataRow dr = namesTable.Rows[i];//打印類型string PrintType = dr["PrintType"].ToString();//換頁if (PrintType == "PAGE" || (i == (namesTable.Rows.Count - 1))){if (curPage < PrintPreview.CurPage){iRow = i + 1;}else{endRow = i + 1;}curPage++;//打印奇數頁if (PrintPreview.CurPage == -1){if (curPage % 2 != 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}else{pintPoints.Add(new Point(preStart, i));}}}//打印偶數頁else if (PrintPreview.CurPage == -2){if (curPage % 2 == 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}else{pintPoints.Add(new Point(preStart, i));}}}//打印偶數頁逆序else if (PrintPreview.CurPage == -3){if (curPage % 2 == 0){if (PrintPreview.RangeStart > 0 && PrintPreview.RangeEnd > 0){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Insert(0, new Point(preStart, i));}}else{pintPoints.Insert(0, new Point(preStart, i));}}}//范圍打印else if (PrintPreview.CurPage == -4){if (curPage >= PrintPreview.RangeStart && curPage <= PrintPreview.RangeEnd){pintPoints.Add(new Point(preStart, i));}}//當前頁開始位置preStart = i + 1;}}//訂閱BeginPrint事件 pdDocument.BeginPrint += new PrintEventHandler(pdDocument_BeginPrint);//定義打印內容pdDocument.PrintPage += new PrintPageEventHandler(OnPrintPage);//訂閱EndPrint事件,釋放資源 pdDocument.EndPrint += new PrintEventHandler(pdDocument_EndPrint);//打印PrintProxy();}}Excel導出從多個模板選一個對接,需要彈窗展示多個模板名稱讓用戶選擇用的模板。通過string fullName = MessageServer.shell.SelectFileDialog(tempExcelPath);驅動UI
驅動地方,
//導出Excelelse if (((inputStrArr[0] == "Export") || (inputStrArr[0] == "ExportFast")) && inputStrArr.Length > 2){string tempExcelPath = inputStrArr[6];//快速導出Excel標識if (inputStrArr[0] == "ExportFast"){ExportUtil.IsExportFast = true;}//選模板的模式if (tempExcelPath.Contains("|")){//選擇模板string fullName = MessageServer.shell.SelectFileDialog(tempExcelPath);if (fullName != ""){inputStrArr[6] = fullName;RealExport(inputStrArr);}}else{RealExport(inputStrArr);}}發消息給UI層
/// <summary>/// 從多個文件選一個彈窗/// </summary>/// <param name="selectStr">用|分割的多個名稱</param>/// <returns></returns>public string SelectFileDialog(string selectStr){if (MessageServer.UIOper != null){return MessageServer.UIOper.ShowSelectTmpFileDialog(selectStr);}Console.WriteLine("沒有UI,默認選擇第一個:");string path = selectStr.Split('|')[0];return path;}electron交互層,這里把組裝的UI消息推送給界面端,界面收到消息做響應
/// <summary>/// 顯示選擇文件對話框/// </summary>/// <param name="selectStr"></param>/// <returns></returns>public string ShowSelectTmpFileDialog(string selectStr){UIMsgDto dto = new UIMsgDto();dto.Type = "SelectTmpFileDialog";dto.NeedRet = true;dto.Paras = new List<string>();dto.Paras.Add(selectStr);//會阻塞等待返回UIMsgDto ret = SenMsgAndWait(dto);if (ret != null){if (ret.RetParas != null && ret.RetParas.Count > 0){return ret.RetParas[0];}}return "";}js處理,處理選擇模板類型消息,展示模板選擇彈窗,把選擇結果發送給服務端。
//選擇模板文件對話框,多選一else if (data.Type == "SelectTmpFileDialog") {var path = data.Paras[0];var pathArr = path.split('|');var buttons = [];for (var i = 0; i < pathArr.length; i++) {var oneArr = pathArr[i].split("/");buttons.push(oneArr[oneArr.length-1]);}var choice = dialog.showMessageBoxSync(mainWindow, {type: "info",buttons: buttons,title: "選擇模板對話框",message: "請選擇要使用的導出模板",defaultId: -1,cancelId: -1});//執行菜單邏輯if (choice >= 0) {data.RetParas = [];data.RetParas.push(pathArr[choice]);console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}else {data.RetParas = [];data.RetParas.push("");console.log("UI->S", "uimsg#" + JSON.stringify(data));ws.send("uimsg#" + JSON.stringify(data));}}通過前后端精密的配合解決DotNetCore沒跨平臺ui的問題。同時實現CS界面和后端解耦合
完美,哈哈,多平臺可用,centos錄屏不好弄,彈窗風格沒windows好,總算實現了完全跨平臺了
總結
- 上一篇: CMD 命令刷新网卡
- 下一篇: Rust引入外部包,VsCode引入失败