【electron】静默打印尺寸控制

4,669 阅读3分钟

前提纪要

本项目使用gitee上 electron-egg 开源项目

目前版本为v3,package依赖版本参考如下

"engines": {
  "node": "16.16.0"
},
"devDependencies": {
  "@electron/rebuild": "^3.2.13",
  "debug": "^4.3.3",
  "ee-bin": "^1.1.0",
  "electron": "^21.4.4",
  "electron-builder": "^23.6.0",
  "eslint": "^5.13.0",
  "eslint-plugin-prettier": "^3.0.1"
},
"dependencies": {
  "better-sqlite3": "^8.4.0",
  "dayjs": "^1.10.7",
  "ee-core": "^2.4.0",
  "electron-updater": "^5.3.0",
  "lodash": "^4.17.21"
}

尝试过近期更新的electron v-25.3.2,存在打印内容过小,不断调整边距也无法修复的问题,经过翻找GitHub后,发现打印尺寸是个通病,时不时在不同的版本中出现,然后又被修好

以下为打印源码

// 进行一次自定义页面打印
async selfPages(data){
  const addonWindow = this.app.addon.window;
  let opt = {
    title: '打印',
    // 是否显示
    show: false,
    width: 450,
    height: 350,
  }
  const name = 'print_' + new Date().getTime();
  const win = addonWindow.create(name, opt);
  
  // load page 加载页面
  win.loadURL('http://github.com');

  // 打印设置
  const options = {
    silent: true,  // 静默打印标识
    printBackground: false,
    margins: {
      marginType: "none"
    },
    // pageSize: "A6",
    pageSize: {
      width: 80000,
      height: 50000,
    },
    deviceName: "Microsoft Print to PDF",  // 不填写时,使用默认打印机
  }
  win.webContents.once('did-finish-load', () => { // 等待页面加载完成过后再打印
    // 开始打印
    let optionsPDF = {
      margins: {
        top: 0,
        bottom: 0,
        left: 0,
        right: 0
      },
      pageSize: {
        width: 3.14,
        height: 1.96,
      }
    }
    // printToPDF方法中的尺寸单位为英寸,无最小值限制
    // win.webContents.printToPDF(optionsPDF).then((data, error) =>{
    //   Log.info(data)
    //   if (error) throw error
    //   fs.writeFile('./out/print.pdf', data, (error) => {
    //     if (error) throw error
    //     Log.info('Write PDF successfully.')
    //     win.close();
    //   })
    // })

    // print尺寸单位为微米 Dimensions in Microns - 1 meter = 10^6 microns
    win.webContents.print(options, (success, errorType) => {
      if (!success) {
        Log.info("error===" + errorType);
        win.close();
        return false;
      }
      Log.info('startPrinting---------');
      win.close();
      return true;
    })
  });
}

接下来就是一步步解释

第一步为创建窗口同时在页面内部加载内容,或直接打印自己的electron页面。下面源码中的创建方法是被electron-egg作者团队封装过的工具类,可以使用BrowserWindow进行创建窗口页面

  const addonWindow = this.app.addon.window;
  let opt = {
    title: '打印',
    // 是否显示
    show: false,
    width: 450,
    height: 350,
  }
  const name = 'print_' + new Date().getTime();
  const win = addonWindow.create(name, opt);
    // load page 加载网页页面
  win.loadURL('http://github.com');
  
  //或加载自己的vue页面
  // win.loadURL(addr+"/#/special/printTemplate?params="+data);

接下来设置打印选项,由于在electron中的printprintToPDF的可选项有不少的差别,同样命名的参数在不同api中的用途也不一样,更多参数可以点进去查看

重点需要说明的是,打印尺寸控制只有静默打印silent: true的时候生效;pagesize能接收的参数有A0A1A2A3A4A5A6LegalLetterTabloid、和包含widthheight的对象;printwidthheight的单位是微米(micron),printToPDFwidthheight的单位英寸(inches)

// 打印设置
const options = {
  silent: true,  // 静默打印标识
  printBackground: false,
  margins: {
    marginType: "none"
  },
  // pageSize: "A6",
  pageSize: {
    width: 80000,
    height: 50000,
  },
  deviceName: "Microsoft Print to PDF",  // 不填写时,使用默认打印机
  // deviceName: "LBP6230dn",  // 不填写时,使用默认打印机
}

// PDF打印参数
let optionsPDF = {
  margins: {
    top: 0,
    bottom: 0,
    left: 0,
    right: 0
  },
  pageSize: {
    width: 3.14,
    height: 1.96,
  }
}

electron目前支持两种打印方式printprintToPDF,如果打印出来的是空白页,或者样式未加载的情况,可以试着加上page-break-before: alwaysprintToPDF获取到的是一个文件流,通过fs写入制定目录即可

const fs = require('fs')
win.webContents.once('did-finish-load', () => { // 等待页面加载完成过后再打印
  // 开始打印
  // printToPDF方法中的尺寸单位为英寸,无最小值限制
  win.webContents.printToPDF(optionsPDF).then((data, error) =>{
    if (error) throw error
    fs.writeFile('./out/print.pdf', data, (error) => {
      if (error) throw error
      win.close();
    })
  })

  // print尺寸单位为微米 Dimensions in Microns - 1 meter = 10^6 microns
  win.webContents.print(options, (success, errorType) => {
    if (!success) {
      win.close();
      return false;
    }
    win.close();
    return true;
  })
});

完。。。

如需转载,请联系作者本人