当前位置:   article > 正文

vue,js,html,识别带二维码的发票前端支持pdf转图片_js 识别发票信息

js 识别发票信息

        由于业务需求需要做一个发票识别内容,然后就有了这个文章。首先这个思路是识别图片上的二维码信息,扫码二维码之后,我们就可以得到发票的基础信息:1、发票类型;2、发票代码;3、发票号码;4、发票效验码;5、发票开具时间;6、发票金额。这些信息就是发票二维码包含的所有的信息了。

其中使用的前端插件:qrcode-decoder,pdfjs-dist(如果你不考虑识别pdf的内容也可以忽略此内容)。

  1. 监听文件发生改变
  1. <el-upload
  2. class="upload-demo mt5"
  3. style="height: 268px; width: 99%"
  4. drag
  5. :show-file-list="false"
  6. :auto-upload="false"
  7. action="#"
  8. method="POST"
  9. ref="fileUploadRef"
  10. accept=".pdf,.jpg,.png,.jpeg"
  11. :on-change="fileChange"
  12. >
  13. <el-icon class="el-icon--upload" style="font-size: 90px; line-height: 90px">
  14. <upload-filled />
  15. </el-icon>
  16. <div class="el-upload__text">拖拽或点击上传发票 <em>仅能自动识别支持带有二维码的发票</em></div>
  17. <div class="el-upload__text">支持格式:pdf、jpg、png等文件</div>
  18. </el-upload>

2.监听方法

  1. async function fileChange(rawFile) {
  2. let fileTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg', 'application/pdf'];
  3. if (!fileTypes.includes(rawFile.raw.type)) {
  4. console.log('存在不支持的格式');
  5. return false;
  6. }
  7. // ts写法 可换成this
  8. imgUrl.value = null;
  9. pdfUrl.value = null;
  10. // 可以用于在浏览器上预览本地图片或者视频,文件
  11. let fileUrl = getObjectURL(rawFile.raw);
  12. // 判断是否是pdf,如果是pdf就需要转成图片在扫码
  13. if (rawFile.raw.type === 'application/pdf') {
  14. pdfUrl.value = fileUrl;
  15. await pdfToImg(rawFile.raw, img => {
  16. dealScanQrCode(img);
  17. });
  18. } else {
  19. // 如果是图片就直接扫描二维码
  20. imgUrl.value = fileUrl;
  21. dealScanQrCode(imgSrc.value);
  22. }
  23. return true;
  24. }

3.封装扫描二维码 

  1. // 扫描识别二维码的方法封装
  2. function dealScanQrCode(imgSrc) {
  3. // 具体的扫描方法
  4. scanQrCode(null, imgSrc, data => {
  5. let dealCode = [];
  6. // data 是返回的数据 判断data是否有异常
  7. if (data) {
  8. //解析后的数据是01,10,044002015551,94449434,548.13,20221117,7649489616555713831,7W7C,
  9. dealCode = data.split(',');
  10. // 如果分个后小于6说明不是发票信息
  11. if (dealCode.length < 6) {
  12. dealCode = [];
  13. }
  14. }
  15. // [0]占位符 [1]、发票类型{01增值税专用发票,04增值税普通发票,10增值税普通发票(电子),08增值税专用发票(电子)};
  16. // [2]、发票代码;[3]、发票号码;[4]开票金额;[5]、发票开具时间;[6]表示发票校验码,增值税专用发票是没有发票校验码的,没有则为空字符串;
  17. // 解析数据
  18. let row ={};
  19. // 发票类型
  20. row .invoiceType = dealCode[1] || null;
  21. // 发票代码
  22. row.invoiceCode = dealCode[2] || null;
  23. // 发票号码
  24. row.invoiceNo = dealCode[3] || null;
  25. let invoiceTotal = dealCode[4] || null;
  26. if (invoiceTotal) {
  27. invoiceTotal = parseFloat(invoiceTotal);
  28. }
  29. // 开票金额
  30. row.invoiceTotal = invoiceTotal;
  31. // 这里是价税合计的算法 首先你得有税率 一般都是13%
  32. let invoiceTaxRatio = row.invoiceTaxRatio || null;
  33. if (invoiceTaxRatio && invoiceTaxRatio > 0 && invoiceTotal) {
  34. // costInvoiceTotal价税合计
  35. let num = invoiceTaxRatio / 100;
  36. let invoiceTaxTotal = (invoiceTotal * num).toFixed(2);
  37. row.costInvoiceTotal = parseFloat(invoiceTotal) + parseFloat(invoiceTaxTotal);
  38. // invoiceTaxTotal税额
  39. row.invoiceTaxTotal = parseFloat(invoiceTaxTotal);
  40. }
  41. // 发票开具时间
  42. let invoiceTime = dealCode[5] || null;
  43. if (invoiceTime) {
  44. // 转换开票金额
  45. invoiceTime = invoiceTime.replace(/^(\d{4})(\d{2})(\d{2})$/, '$1-$2-$3');
  46. }
  47. row.invoiceTime = invoiceTime;
  48. });
  49. }

4.封装工具 utils.js

  1. // 扫码插件
  2. import QrCode from 'qrcode-decoder';
  3. // pdf转图片
  4. import * as pdfJs from 'pdfjs-dist';
  5. // pdfworker地址
  6. import * as pdfWorkerMin from 'pdfjs-dist/build/pdf.worker.min?url';
  7. // 这里要初始化一下路由防止异常,不然转换的时候会报错
  8. pdfJs.GlobalWorkerOptions.workerSrc = pdfWorkerMin.default;
  9. /**
  10. * 文件转成预览链接
  11. * @param file
  12. * @returns {null}
  13. */
  14. export const getObjectURL = file => {
  15. let url = null;
  16. if (window.createObjectURL !== undefined) {
  17. // basic
  18. url = window.createObjectURL(file);
  19. } else if (window.URL !== undefined) {
  20. // mozilla(firefox)
  21. url = window.URL.createObjectURL(file);
  22. } else if (window.webkitURL !== undefined) {
  23. // webkit or chrome
  24. url = window.webkitURL.createObjectURL(file);
  25. }
  26. return url;
  27. };
  28. /**
  29. * 识别二维码
  30. * @param file 文件
  31. * @param url 地址
  32. * @param callback 回调函数
  33. */
  34. export const scanQrCode = (file, url, callback) => {
  35. // 获取临时路径
  36. let tempUrl = url || '';
  37. if (file) {
  38. tempUrl = getObjectURL(file);
  39. }
  40. // 初始化
  41. const qr = new QrCode();
  42. // 解析二维码,返回promise
  43. qr.decodeFromImage(tempUrl).then(res => {
  44. if (callback) {
  45. callback(res.data);
  46. }
  47. });
  48. };
  49. /**
  50. * pdf转图片
  51. * @param file 文件信息
  52. * @param callBack 回调函数
  53. */
  54. export const pdfToImg = (file, callBack) => {
  55. // 文件转获取pdf地址
  56. let url = getObjectURL(file);
  57. //这里是重点,然后将流数据转换为url,CMapReaderFactory方法在进行处理
  58. pdfJs.getDocument(url).promise.then(pdf => {
  59. // pdf多个文件的情况下
  60. for (let num = 1; num <= pdf.numPages; num++) {
  61. // 分页查询
  62. pdf.getPage(num).then(async page => {
  63. // 获取pdf具体数据
  64. const viewport = page.getViewport({ scale: 1.0 });
  65. // 创建画布
  66. const canvas = document.createElement('canvas');
  67. const context = canvas.getContext('2d');
  68. // 处理画布高宽
  69. canvas.height = viewport.height;
  70. canvas.width = viewport.width;
  71. // 读取数据进行画布转换
  72. page.render({ canvasContext: context, viewport: viewport }).promise.then(() => {
  73. if (callBack) {
  74. // 出发回调函数
  75. callBack(canvas.toDataURL('image/jpeg'));
  76. // 释放资源
  77. canvas.remove();
  78. }
  79. });
  80. });
  81. }
  82. });
  83. };

注意!注意!注意 !

这里pdf转图片的时候是没有处理字符库的(会抛出异常信息,不影响操作),转换的后的发票图片是空白的没有具体的内容但是有二维码信息,如果你需要处理的话,请自行查询方法。

异常截图:

Warning: loadFont - translateFont failed: "UnknownErrorException: The CMap "baseUrl" parameter must be specified, ensure that the "cMapUrl" and "cMapPacked" API parameters are provided.".

5.预览

  1. <!-- 图片直接用element的图片插件-->
  2. <el-image v-if="imgUrl" :src="imgUrl" style="width: 100%; height: 268px" fit="contain">
  3. <template #placeholder>
  4. <div class="image-slot">加载中<span class="dot">...</span></div>
  5. </template>
  6. </el-image>
  7. <!-- pdf直接调用浏览器的预览-->
  8. <iframe v-if="pdfUrl" :src="pdfUrl + `#toolbar=0&zoom=50 `" width="100%" height="268" frameborder="0" />

 - 图片直接用element的图片插件

- pdf直接调用浏览器的预览 这里携带了参数信息toolbar=0&zoom=50  ,toolbar=0代表不需要工具栏,zoom=50 是代表缩放了50%

End;

        由于项目实际应用中,发现识别成功率过低,而且扫描件经常识别不到二维码,或者带有icon的二维码,识别率也惨不忍睹,后面引入了opencv-js-qrcode进行再次优化提升,提高了识别率。

vue,js,html 根据 opencv-js-qrcode 识别发票二维码信息-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/280004
推荐阅读
相关标签
  

闽ICP备14008679号