找回密码
 立即注册

QQ登录

只需一步,快速开始

Richard.Huang SpreadJS 开发认证

超级版主

44

主题

3259

帖子

5081

积分

超级版主

Rank: 8Rank: 8

积分
5081

SpreadJS 认证SpreadJS 高级认证

Richard.Huang SpreadJS 开发认证
超级版主   /  发表于:2024-12-10 14:30  /   查看:64  /  回复:0
本帖最后由 Richard.Huang 于 2024-12-10 14:32 编辑

场景:计量检测行业填报模板设计

在特种设备检测行业中,客户面临着一系列与计量检测相关的挑战。这些挑战不仅体现在需要处理多种类型的检测模板上,还涉及到确保每种特种设备(如电梯、锅炉等)的检测参数准确无误地记录下来。为了应对这些问题,某大型特种设备检测行业的客户寻求一种解决方案,以实现更加高效的数据管理流程,并减少人工干预所带来的潜在错误和工作量。

针对这一需求,SpreadJS 提供了一个理想的解决方案,它能够提供类Excel的原生体验,支持在线创建和编辑复杂的计量检测模板。通过使用 SpreadJS,用户可以轻松设计包含各种复杂计算公式、样式以及数据验证规则的表格文档,从而满足不同特种设备检测的具体要求。更重要的是,SpreadJS具备强大的API接口和技术支持服务,可以帮助开发者快速实现将不同类型的计量检测模板中的数据区域提取为结构化数据的功能,确保后续自动化抓取用户填报的数据及分析过程顺利进行。

特别值得注意的是,在这个过程中保证数据绑定路径及其对应位置信息的准确性至关重要。对于像编号编码这样的关键字段来说,任何遗漏或错误都可能导致严重的后果。因此,采用SpreadJS后,系统开发人员可以通过定义明确的数据模型来指定每个单元格的内容如何映射到后台数据库中的特定字段,这样不仅可以防止重要信息丢失,而且有助于维持整个系统的数据一致性。此外,SpreadJS内置了丰富的功能用于管理和维护数据绑定关系,例如当检测报告中的信息分别由供应商人员和厂家外检人员填写时,角色不同意味着能输入的单元格也有所不同,而SpreadJS可以精确控制这些权限,确保只有授权用户才能修改特定部分的数据。

总之,借助于SpreadJS提供的高级特性和灵活性,该大型特种设备检测行业的客户将能够更有效地管理和优化其众多的检测模板。这不仅减少了大量的人工处理任务,提高了工作效率,同时也增强了数据完整性和准确性,使得企业在面对日益增长的业务需求时更加从容不迫。同时,由于SpreadJS的高度兼容性和易用性,最终用户无需额外培训即可快速上手操作,进一步促进了业务流程的顺畅运行。
image.png15408019.png

难点:手绘模板重复操作过多,手动设置绑定路径操作繁琐

在计量检测行业中,模板设计是一个至关重要的环节,它直接关系到后续数据填报的准确性和效率。然而,当前的模板设计流程中存在着显著的痛点:不同类型的设备和测试项目需要定制化的参数设置,这导致了Excel模板中的数据填报区域与预设不一致的情况频繁发生。此外,传统的代码批量扫描单元格并设定绑定路径的方法虽然可以在一定程度上减少模板设计人员的工作量,但由于行业特性和非标准化的需求,这种方法往往会导致较多的错误,反而增加了工作负担。

面对这样的挑战,确实存在更智能的方式来优化这一过程——引入人工智能(AI)技术。通过AI来辅助完成数据绑定操作,可以显著减轻模板设计人员乃至系统开发人员的时间消耗。具体而言:

1. 智能化的数据绑定:利用机器学习算法分析大量已有的模板样本,自动识别出哪些单元格应该与数据库中的哪些字段相匹配。这种基于模式识别的技术能够适应不同的模板结构,并根据上下文环境动态调整绑定规则。例如,在处理电梯或锅炉等特种设备的检测报告时,AI可以根据设备类型自动选择正确的绑定方案。
2. 自适应学习机制:随着更多模板被创建和使用,AI系统将不断积累经验,逐步提高其预测精度。这意味着即使初次设置可能不够完美,但随着时间推移,AI会越来越精准地理解特定行业的特殊需求,从而提供更加贴合实际业务场景的服务。
3. 用户反馈循环:允许最终用户对AI生成的结果进行审查和修正,确保关键信息如编号编码不会出现任何遗漏或误报。同时,这些反馈也将作为训练数据回馈给AI模型,进一步提升其性能。这种方式不仅提高了初期配置的质量,也促进了持续改进的过程。
4. 降低人工干预度:一旦建立了可靠的AI驱动的数据绑定系统,大部分基础性任务都可以自动化完成,使得技术人员可以把更多精力投入到复杂问题解决上去。对于那些确实需要人工介入的地方,AI还可以提供指导建议,帮助快速定位潜在问题所在。
5. 增强灵活性和支持多样化需求:考虑到计量检测行业的多样性和变化性,AI解决方案应当具备足够的灵活性以应对各种新的要求。比如当遇到从未见过的新类型设备时,系统应能迅速调整自身逻辑框架,为新情况找到合适的解决方案。

综上所述,采用AI技术来进行数据绑定不仅可以大幅减少模板设计人员的手动工作量,还能有效避免因人为失误造成的各类问题。更重要的是,它为计量检测行业带来了一种全新的、更为高效的模板管理方式,有助于推动整个行业的数字化转型和发展。通过这种方式,我们不仅解决了虽然不是核心痛点但却占用大量时间的工作,还提升了整体工作效率和服务质量。

合作:SpreadJS + GcExcel + AI

因此,我们想到在原有方案的基础上加入AI作为辅助,让SpreadJS+GcExcel与AI协同工作:

流程图

image.png599051208.png

代码步骤

一、提取区域

总的技术方案是将需要处理的区域通过SpreadJS的API拿取出来,为了方便AI的识别,我们需要将SpreadJS拿出来的区域变成AI比较容易理解的HTML的格式,并且为了减少HTML的体积,我们建议将导出的HTML内容进行精简,保留必要的合并单元格等信息以及数据信息即可,至于单元格的样式等,都可以抛弃
  1. const range = sheet.getRange(usedRange.row, usedRange.col, usedRange.rowCount, usedRange.colCount);
  2. const html = range.toHtml();
  3. // 解析HTML字符串,去除元素样式属性,获取处理后的HTML
  4. const cleanedHtml = cleanHtml(html);

  5. //--------------------------------
  6. // 解析HTML字符串并清理元素样式属性
  7. function cleanHtml(html) {
  8.     const parser = new DOMParser();
  9.     const doc = parser.parseFromString(html, "text/html");
  10.     const allElements = doc.body.getElementsByTagName("*");
  11.     for (const element of allElements) {
  12.         if (element.hasAttribute("style")) {
  13.             element.removeAttribute("style");
  14.         }
  15.     }
  16.     return doc.body.innerHTML;
  17. }
复制代码

二、前后端文件传输
前端:
  1. // 保存文件并处理响应
  2. await spread.save(async (file) => {
  3.     const formData = new FormData();
  4.     formData.append('file', file);
  5.     formData.append('cleanedHtml', cleanedHtml);
  6.     formData.append('jsonSchema', jsonSchema);// 将右侧字段列表也传给后端统一处理,方便整个文件更新后右侧字段列表也能对应添加上数据字段

  7.     try {
  8.         const response = await fetch('/api/process', {
  9.             method: 'POST',
  10.             body: formData
  11.         });

  12.         if (response.ok) {
  13.             await downloadFile(spread, response, centerDiv);
  14.             const jsondata = response.headers.get('X-Extra-Info');
  15.             const extraInfo = decodeURIComponent(jsondata.replace(/\+/g, ' '));
  16.             // 更新相关数据
  17.             updateDesignerData(designer, extraInfo);
  18.         } else {
  19.             console.error('Failed to upload file:', response.statusText);
  20.         }
  21.     } catch (error) {
  22.         console.error('Error during file upload:', error);
  23.     }
  24. }, (e) => console.log(e));
复制代码

后端
  1. @PostMapping("/process")
  2. public ResponseEntity<InputStreamResource> processFile(
  3.         @RequestParam("file") MultipartFile file,
  4.         @RequestParam("cleanedHtml") String cleanedHtml,
  5.         @RequestParam("jsonSchema") String jsonSchema) throws IOException {

  6.     // 校验文件是否为空,为空则直接返回错误响应
  7.     if (file.isEmpty()) {
  8.         return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
  9.     }

  10.     try (InputStream inputStream = file.getInputStream()) {
  11.         Workbook workbook = new Workbook();
  12.         // 打开上传的文件,使用try-with-resources确保资源正确关闭
  13.         workbook.open(inputStream, OpenFileFormat.Sjs);

  14.         // 组合文本内容,准备与AI交互的提示信息
  15.         String text = TextTool.HtmlStringCombiner("prompts/start.txt", "prompts/end.txt", cleanedHtml);

  16.         // 使用ObjectMapper处理右侧字段列表JSON相关操作
  17.         ObjectMapper mapper = new ObjectMapper();
  18.         JsonNode rootNode = mapper.readTree(jsonSchema);

  19.         String newJsonSchema = "";
  20.         if (rootNode instanceof ObjectNode) {
  21.             ObjectNode propertiesNode = (ObjectNode) rootNode.get("properties");
  22.             IWorksheet worksheet = workbook.getActiveSheet();
  23.             try {
  24.                 // TODO 调用AI服务获取结果并处理
  25.                 // ...
  26.             } catch (ApiException | NoApiKeyException | InputRequiredException e) {
  27.                 // 记录异常信息,建议使用日志框架替代System.err.println
  28.                 LOGGER.severe("An error occurred while calling the generation service: " + e.getMessage());
  29.             }
  30.         }

  31.         // 将修改后的Workbook保存到字节数组输出流
  32.         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
  33.             workbook.save(outputStream, SaveFileFormat.Sjs);
  34.             byte[] fileBytes = outputStream.toByteArray();

  35.             // 创建InputStreamResource用于返回给客户端
  36.             InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(fileBytes));

  37.             // 设置响应头信息
  38.             HttpHeaders headers = new HttpHeaders();
  39.             headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=generated_file.txt");
  40.             headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
  41.             headers.add("Pragma", "no-cache");
  42.             headers.add("Expires", "0");
  43.             headers.add("X-Extra-Info", newJsonSchema);

  44.             return ResponseEntity.ok()
  45.                     .headers(headers)
  46.                     .contentLength(fileBytes.length)
  47.                     .contentType(MediaType.TEXT_PLAIN)
  48.                     .body(resource);
  49.         }
  50.     } catch (IOException e) {
  51.         // 捕获更上层的IOException并处理,可根据实际情况进行更精细的异常处理或重新抛出
  52.         LOGGER.severe("An error occurred during file processing: " + e.getMessage());
  53.         throw e;
  54.     }
  55. }
复制代码

三、编写prompt

这段内容是整个AI对接的核心,好的prompt template才能通过AI获取到好的结果,并且注意要让AI返回我们规定的格式内容才能让我们后续的操作更加容易。以qwen-long模型为例,我给到的prompt template如下:
  1. 我有一个从剪贴板获取的HTML格式表格内容,用于在Excel软件中粘贴。这个HTML字符串不仅包含了文本信息,还包含了CSS样式和合并单元格的信息。我现在希望你能帮我解析这个表格,并确定哪些是数据区域,即那些应该填写实际数据的单元格位置。请按照以下规则来分析并给出结果:
  2. 1. **坐标系统**: 假设左上角的单元格坐标为(0, 0),横坐标(列)随着向右增加而增大,纵坐标(行)随着向下增加而增大。
  3. 2. **数据区域定义**: 数据区域是指那些没有被标题或固定文本占用、预期将要填入具体数据的单元格。如果一个单元格有固定的文本或作为标题使用,则不被视为数据区域的一部分。
  4. 3. **输出格式**: 请提供每个数据区域的起始坐标(左上角)和结束坐标(右下角),以及该区域内应填写的数据类型或字段名称。例如:

  5.    ```
  6.    [
  7.        {
  8.            "startRow": 1,
  9.            "endRow": 2,
  10.            "startCol": 3,
  11.            "endCol": 4,
  12.            "data": "客户名称"
  13.        },
  14.        {
  15.            "startRow": 1,
  16.            "endRow": 2,
  17.            "startCol": 3,
  18.            "endCol": 4,
  19.            "data": "成员构成"
  20.        }
  21.    ]
  22.    ```

  23. 4. **HTML内容**: 下面是我提供的HTML字符串,请基于此进行解析。

  24.    ```
  25.    {text}
  26.    ```

  27. 请输出结构化的JSON信息。注意要返回完整的数据,不能遗漏,不能省略;对于包含多行的项目用列表表示;只输出JSON不要输出任何额外内容;不同行的内容应该分别输出
复制代码

四、对接AI

这里我是用的qwen-long模型,因为该模型可输入解析的文本长度很大,便于我们后续分析比较大的模板。对接的基础操作我不做过多赘述,在最后的参考链接中可以找到基础的对接操作,这里只写我们的对接代码:
  1. private String callWithMessage(String content) throws ApiException, NoApiKeyException, InputRequiredException {
  2.     Generation gen = new Generation();
  3.     Message systemMsg = Message.builder()
  4.             .role(Role.SYSTEM.getValue())
  5.             .content("You are a helpful assistant.")
  6.             .build();
  7.     Message userMsg = Message.builder()
  8.             .role(Role.USER.getValue())
  9.             .content(content)// 这里content就是组合好的提问内容
  10.             .build();
  11.     GenerationParam param = GenerationParam.builder()
  12.             .apiKey(apiKey)// 换成自己的apiKey
  13.             .model(aiModel)// 换成自己的aiModel
  14.             .messages(Arrays.asList(systemMsg, userMsg))
  15.             .resultFormat(GenerationParam.ResultFormat.MESSAGE)
  16.             .build();
  17.     GenerationResult call = gen.call(param);
  18.     List<GenerationOutput.Choice> choices = call.getOutput().getChoices();
  19.     return choices.get(0).getMessage().getContent();// 返回AI返回的结果
  20. }
复制代码

效果:

导入:
image.png894286804.png

右键解析文件:
image.png155533141.png

解析:
image.png900027160.png

最终效果:
image.png643554076.png

总结:高效利用已有模板,AI助力计量检测行业最后一公里

通过SpreadJS搭配后端GcExcel通过代码方式为用户模板设置单元格绑定路径的方式在操作性能上表现出色,但缺乏对用户本身模板内容的识别和上下文理解能力。而AI大模型具有强大的特征提取和抽象能力,可以有效捕捉数据中的潜在关联和复杂性。将这两种技术相融合,能够有效减少误识别的几率,实现更高精度的识别结果。两种技术的优劣势相互补充,形成一种更具适应性、灵活性和高效性的解决方案。

大模型并非“万能”的,支持服务的客户越多,就越能体会到“能不让大模型做的事情就不让它做”的实践经验对提升效果的重要性。许多传统方法仍然在特定领域下表现出色,可以为大模型提供前置输入处理。另外,从计算资源和响应时延的角度来看,SpreadJS+GcExcel的传统编码方式的技术相对于大模型也具有不少优势。结合SpreadJS+GcExcel可以满足实时性和高效性的需求,从而增强用户体验。

将AI大模型与SpreadJS以及GcExcel融合,不仅能弥补各自的不足,还能在多个层面提升信息处理的能力和效率。这种融合不仅是技术发展的必然趋势,也是推动计量检测行业的智能化转型的重要驱动力。

参考链接:
1. https://help.aliyun.com/zh/model-studio/user-guide/text-generation?spm=a2c4g.2712809.0.0.72731507x6iuVp

Demo: AISetBinding.rar (62.21 KB, 下载次数: 1)

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部