Skip to content

摩尔打印使用指南

前提条件

  1. 必须安装C-Lodop,下载方式:从新软件商店里面直接搜索摩尔打印,直接下载安装即可。

  1. 使用C-Lodop推荐使用google浏览器

使用步骤

硬件方面

  1. 添加打印机ZDesigner ZT410-300dpi ZPL
  2. 将当前打印机设置为默认打印机
  3. 将当前打印机的浓度设置到最高
  4. 设置该打印机为默认打印机

软件方面

这边按照公司的框架(React+umi)来介绍

  1. 因为C-Lodop目前并不支持npm下载,所以需要直接引入到入口文件里

具体操作步骤:

- 找到项目的入口文件`src/pages/document.ejs`
- 当有多个引用时,用name设置新变量名来区分调用 `<script src='[http://localhost:8000/CLodopfuncs.js?name=CLODOPA'></script>](http://localhost:8000/CLodopfuncs.js?name=CLODOPA'></script>)`到`body`里面(一定要将`C-Lodop`安装到本地,否则访问不到)
  1. 导入Lodop

具体操作步骤:

- 方法一:
    * 前往[下载中心 - Lodop和C-Lodop官网主站](http://www.c-lodop.com/download.html)下载适合win32的发行版
    * 解压,不安装,从目录中拿出`LodopFuncs.js`文件,放到你自己的项目目录下面(`utils`目录之类的)
- 方法二(推荐)
    * [LodopFuncs.js](https://www.yuque.com/attachments/yuque/0/2023/js/36211166/1695284476810-600b5009-8ca9-4513-bb8a-ab5521abc6fb.js),直接下载,放到自己的项目目录下
  1. 修改LodopFuncs.js文件(如果使用方法二,那么不用走这一步)

具体操作步骤:

- 将所有函数暴露`needCLodop()`,`checkOrTryHttp()`,`getLodop()`
- 修改`loadCLodop()`这个立即执行函数

setTimeout("checkOrTryHttp", 200)改为setTimeout(checkOrTryHttp, 200)

否则会报错:checkOrTryHttp is not defined

javascript
(function loadCLodop() {
    if (!needCLodop()) return;
    CLodopIsLocal = !!((URL_WS1 + URL_WS2).match(/\/\/localho|\/\/127.0.0./i));
    LoadJsState = "loadingA";
    if (!window.WebSocket && window.MozWebSocket) window.WebSocket = window.MozWebSocket;
    //ws方式速度快(小于200ms)且可避免CORS错误,但要求Lodop版本足够新:
    try {
        var WSK1 = new WebSocket(URL_WS1);
        WSK1.onopen = function (e) {
            // console.log("WSK1");
            setTimeout(checkOrTryHttp, 200);
        }
        WSK1.onmessage = function (e) { if (!window.getCLodop) eval(e.data); }
        WSK1.onerror = function (e) {
            var WSK2 = new WebSocket(URL_WS2);
            WSK2.onopen = function (e) {
                // console.log("WSK2");
                setTimeout(checkOrTryHttp, 200);
            }
            WSK2.onmessage = function (e) { if (!window.getCLodop) eval(e.data); }
            WSK2.onerror = function (e) {
                // console.log("WSK2-error");
                checkOrTryHttp();
            }
        }
    } catch (e) {
        // error: checkOrTryHttp is not defined 如何解决?
        console.log("error");
        checkOrTryHttp();
    }
})();
- 修改`getLodop()`函数
    * 版本判断的`CLODOP`改为`LODOP`
javascript
if (isLinuxX86 && LODOP.CVERSION < "7.0.4.3") {
  // console.log("版本1");
  strAlertMessage = strLodop7Update_X86;
}
else if (isLinuxARM && LODOP.CVERSION < "7.0.4.3") {
  // console.log("版本2");
  strAlertMessage = strLodop7Update_ARM;
}
else if (LODOP.CVERSION < "6.5.7.7") {
  // console.log("版本3");
  strAlertMessage = strCLodopUpdate;
}
    * 将`document.body.innerHTML = strAlertMessage + strInstallOK+document.body.innerHTML`这段代码删除

因为,我们目前的版本是低于6.5.7.7,所以CLodop会建议我们升级,但是,这种直接改变innerHtml的方法在导致页面卡住(页面只能拿到内容,但是上面的方法拿不到),所以我们直接删除这代码即可。

    * 这个代码里面还有很多是可以修改的,可以按照需求自行修改

实际使用

实现图片打印功能

具体在项目中的使用,请在钉钉联系 [@summer] 沈仙(工号:SC9910)获取密码

图片打印相对于pdf文件打印要稍微简单一些,最主要的就是处理将二进制文件转化为图片的base64格式

个人觉得这种方式并不好:

  1. 当前这个函数需要接受的类型是一个blob类型,其实对前端和后端而言都不是很友好。如果后端直接返回给你一个文件,那么基本的响应格式,就会丢失掉。
  2. 当然后端也可以给你返回一个图片路径,然后你自己去转化。但是图片需要考虑很多因素,最主要的是清晰程度。
javascript
// 导入lodop
import { getLodop } from "@/utils/LodopFuncs"

// 使用lodop打印,实现直接传递url打印
export const print = (blob: Blob) => {
  // 获取lodop,初始化打印函数
  const lodop = getLodop();
  // 打印
  lodop.PRINT_INIT();
  // 设置纸张大小,portrait纵向,大小为30mm*30mm
  lodop.SET_PRINT_PAGESIZE(1, 300, 300, '');
  // 将二进制图片转换成base64
  const reader = new FileReader();
  reader.readAsDataURL(blob);
  reader.onload = function (e) {
    // 将base64里面的回车换行去掉
    const base64 = (e.target?.result as string).replace(/[\r\n]/g, "");
    lodop.ADD_PRINT_IMAGE(0, 0, "100%", "100%", base64);
    lodop.SET_PRINT_STYLEA(0, "Stretch", 1);
    // 添加注册信息
    lodop.SET_LICENSES("摩尔元数(厦门)科技有限公司", "F029DF258EE17DEABD13D0E8A683CAF4", "摩爾元數(廈門)科技有限公司", "1188C10A19B1FFC2F8C382131A6AD529");
    lodop.SET_LICENSES("THIRD LICENSE", "", "MOREWIS (Xiamen) Technology Co.,Ltd.", "1F133D2563465F3FDD16CCA3ADD0878A");
    // 直接打印
    lodop.PRINT()
  }
}

实现打印pdf文件功能

INFO

想要使用打印pdf功能,那么插件版本需要大于,6.5.7.7!!!

打印pdf文件的好处,最主要的就是,你的文件长什么样子,打印出来就是什么样子。

他的难点在于:

  1. 如果他是http那么你可能不会遇到打印出来是白屏的情况,对于https,官方也建议你先下载下来,然后再去打印。
  2. 现在的难点就变成了,如何后台下载,并且获取到文件

谈谈我对官网demo的理解:

1. 他会对`url`(我们获取到的文件地址)进行一个`get`请求,这样他获取到的响应体里面就是文件。
2. 并且我们将文件的类型设置为`MimeType = text/plain`
3. 然后我们会使用`uint8Array`来承接这个响应 `uint8Array`是一个 **无符号的八位整数,用它可以避免中文乱码问题**
  1. 接下来只要处理,将uint8Array展示为base64格式,然后进行打印就可以了
typescript
interface PrintOptions {
  width?: number;
  height?: number;
  order?: number;
  type?: string;
  url: string;
}
export const print = (params: PrintOptions) => {
  const { width, height, url, order = 1, type } = params;
  const base64 = downloadPdf(url);
  const lodop = getLodop();
  if (!lodop) {
    return;
  }
  lodop.PRINT_INIT("");
  lodop.SET_PRINT_PAGESIZE(order, width, height, type);
  lodop.SET_LICENSES(
    "摩尔元数(厦门)科技有限公司",
    "F029DF258EE17DEABD13D0E8A683CAF4",
    "摩爾元數(廈門)科技有限公司",
    "1188C10A19B1FFC2F8C382131A6AD529"
  );
  lodop.SET_LICENSES(
    "THIRD LICENSE",
    "",
    "MOREWIS (Xiamen) Technology Co.,Ltd.",
    "1F133D2563465F3FDD16CCA3ADD0878A"
  );
  // 验证lodop的版本号
  if (lodop.VERSION < "6.5.7.7") {
    return;
  }
  lodop.SET_PRINT_MODE("PRINT_PAGE_PERCENT", true); // 打印页面设置为100%
  lodop.SET_PRINT_STYLEA(0, "Stretch", 2); // (可变形)扩展缩放模式
  // lodop.PRINT();
  lodop.PREVIEW();
};

参数说明:

注意:width/heghttype 必须填一种

typescript
interface PrintOptions {
  width?: number; // 文件长度
  height?: number; //文件高度
  order?: number; // order:横纵向 1:纵向 2:横向
  type?: string; //类型,可以填写A4,A3这种
  url: string; //当前文件路径
}

//请求示例
print({
  url: imgSrc,
  width: 280,
  height: 280,
  order: 1,
});

print({
  url: url,
  type: "A4",
  order: 2
});
typescript
/**
 * 下载pdf
 */
function downloadPdf1(url: string) {
  let arrayBuffer: boolean = false;
  let dataArray: Uint8Array | null = null;
  // 判断是不是https开头
  if (!url.startsWith("https")) {
    return url;
  }
  const xhr = new XMLHttpRequest();
  xhr.open("GET", url, false); // 同步请求,防止异步请求导致的数据不完整
  if (xhr.overrideMimeType) { // overrideMimeType是为了让浏览器识别出responseType
    try {
      xhr.responseType = "arraybuffer"; // 以二进制的方式返回数据
      arrayBuffer = true; // 用来判断返回的数据是不是二进制的
    } catch (error) {
      xhr.overrideMimeType("text/plain; charset=x-user-defined"); // 重写响应头
    }
  }
  xhr.send(null);// get请求不需要参数, send发送以后,xhr.response就是返回的数据 
  let data = xhr.response;
  if (typeof Uint8Array !== "undefined") {  // 如果支持Uint8Array
    if (arrayBuffer) {
      dataArray = new Uint8Array(data);
    } else { // 如果不支持arraybuffer,就用循环的方式转换
      dataArray = new Uint8Array(data.length);
      for (let i = 0; i < data.length; i++) {
        dataArray[i] = data.charCodeAt(i) & 0xff; // &0xff 可以把一个数转换成一个无符号的8位整数
      }
    }
  }
  return getBASE64(dataArray!);
}
typescript
/**
 * @description: 将Unit8Array转换成base64
 */
function getBASE64(dataArray: Uint8Array) {
  const digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  let strData = "";
  for (let i = 0; i < dataArray.length; i += 3) {
    const b1 = dataArray[i] & 0xFF, b2 = dataArray[i + 1] & 0xFF, b3 = dataArray[i + 2] & 0xFF;
    const d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
    const d3 = i + 1 < dataArray.length ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
    const d4 = i + 2 < dataArray.length ? (b3 & 0x3F) : 64;
    strData += digits[d1] + digits[d2] + digits[d3] + digits[d4];
  }
  return strData;
}

参考链接:

  1. Lodop和C-Lodop官网网址
  2. PDF Printer(右键可以看源码)