欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > 将大模型生成数据存入Excel,并用增量的方式存入Excel

将大模型生成数据存入Excel,并用增量的方式存入Excel

2025/4/17 16:17:49 来源:https://blog.csdn.net/Blue_Pepsi_Cola/article/details/143883758  浏览:    关键词:将大模型生成数据存入Excel,并用增量的方式存入Excel

将大模型生成数据存入Excel,并用增量的方式存入Excel

  • 1. 需求与要解决的问题
  • 2. 代码
  • 3. 部分代码分析

1. 需求与要解决的问题

首先就是大模型对话特别耗时,所以通过需要异步执行。
其次是中间对话会有终端或像死锁的那种情况,循环不再继续,所以要增量存到Excel。
最后就是多线程并发,与并发线程数量的控制,因为模型不支持太多线程并发执行。

2. 代码

@Async@Overridepublic void generateMilitaryDescription() {log.info("开始执行 generateMilitaryDescription 方法");String outputPath = "/Users/fanzhen/Documents/tuijian-java-copy/src/main/java/com/landinn/common/client/military_descriptions.xlsx";XSSFWorkbook workbook;XSSFSheet sheet;int[] rowIndex = {1}; // 行索引初始化// 用于存储已存在的 golaxy_node_id 和 golaxy_vocab_idSet<String> existingVocabIds = new HashSet<>();// 检查文件是否存在File file = new File(outputPath);if (file.exists()) {try (FileInputStream fileIn = new FileInputStream(file)) {workbook = new XSSFWorkbook(fileIn); // 读取现有文件sheet = workbook.getSheetAt(0); // 获取第一个工作表rowIndex[0] = sheet.getLastRowNum() + 1; // 计算新数据的起始行log.info("检测到现有文件,从第 {} 行开始追加", rowIndex[0]);// 将现有的golaxy_vocab_id 存入集合for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第 1 行开始读取数据Row row = sheet.getRow(i);if (row != null) {Cell vocabIdCell = row.getCell(1); // 第 2 列为 golaxy_vocab_idif (vocabIdCell != null && vocabIdCell.getCellType() == CellType.STRING) {existingVocabIds.add(vocabIdCell.getStringCellValue());}}}} catch (IOException e) {log.error("读取现有文件时出错: {}", e.getMessage(), e);return;}} else {// 如果文件不存在,则创建新的文件和工作表workbook = new XSSFWorkbook();sheet = workbook.createSheet("军事描述");// 创建标题行Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("golaxy_node_id");headerRow.createCell(1).setCellValue("golaxy_vocab_id");headerRow.createCell(2).setCellValue("node_name");headerRow.createCell(3).setCellValue("description");headerRow.createCell(4).setCellValue("created_at");headerRow.createCell(5).setCellValue("updated_at");log.info("未检测到文件,创建新文件");}// 查询未删除的节点List<TechniqueTreeNode> techniqueTreeNodes = techniqueTreeNodeMapper.selectAll();log.info("共检索到 {} 条 TechniqueTreeNode 数据", techniqueTreeNodes.size());// 创建线程池,限制最高并发为 2ThreadPoolExecutor executor = new ThreadPoolExecutor(2,  // 核心线程数2,  // 最大线程数90,TimeUnit.SECONDS,new SynchronousQueue<>(), // 不允许任务排队,任务必须直接交给线程处理new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝的任务由调用线程执行);Semaphore semaphore = new Semaphore(2); // 限制并发任务数for (TechniqueTreeNode node : techniqueTreeNodes) {// 将 golaxy_node_id 和 golaxy_vocab_id 转为字符串String golaxyNodeId = String.valueOf(node.getGolaxyNodeId());String golaxyVocabId = String.valueOf(node.getGolaxyVocabId());// 检查是否已存在if (existingVocabIds.contains(golaxyVocabId)) {log.info("golaxy_vocab_id '{}' 已存在,跳过该节点", golaxyVocabId);continue;}executor.submit(() -> {try {semaphore.acquire(); // 获取许可} catch (InterruptedException e) {throw new RuntimeException(e);}try {String nodeName = node.getNodeName();log.info("正在处理节点名称:{}", nodeName);String threadName = Thread.currentThread().getName();log.info("线程 {} 开始处理节点 '{}'", threadName, nodeName);long startTime = System.currentTimeMillis();String resultRes = chatModelClient.chatModel(nodeName + "的发展,对军事装备会带来哪些影响?请分别按照军事应用场景列出并详细描述。");String result = "\n # 军事领域应用前景 \n" + resultRes;long endTime = System.currentTimeMillis();log.info("线程 {} 调用模型生成对话完成,耗时:{} 秒", threadName, (endTime - startTime) / 1000.0);log.info("节点 '{}' 的描述结果:{}", nodeName, result);// 写入 Excel 数据并立即保存到文件synchronized (sheet) {Row row = sheet.createRow(rowIndex[0]++);// 创建每个单元格并设置为文本格式Cell cell0 = row.createCell(0);cell0.setCellValue(golaxyNodeId);Cell cell1 = row.createCell(1);cell1.setCellValue(golaxyVocabId);Cell cell2 = row.createCell(2);cell2.setCellValue(nodeName);Cell cell3 = row.createCell(3);cell3.setCellValue(result);// 设置 created_at 和 updated_at 为文本格式Cell cell4 = row.createCell(4);cell4.setCellValue(DateUtil.format(node.getCreatedAt(), "yyyy-MM-dd HH:mm:ss"));Cell cell5 = row.createCell(5);cell5.setCellValue(DateUtil.format(node.getUpdatedAt(), "yyyy-MM-dd HH:mm:ss"));// 增量保存文件try (FileOutputStream fileOut = new FileOutputStream(outputPath)) {workbook.write(fileOut);log.info("Excel 文件已增量更新至 {}", outputPath);} catch (IOException e) {log.error("增量更新文件时出错:{}", e.getMessage(), e);}}log.info("节点 '{}' 处理成功", nodeName);} catch (Exception e) {log.error("处理节点 '{}' 时发生错误:{}", node.getNodeName(), e.getMessage(), e);} finally {semaphore.release(); // 释放许可}});}executor.shutdown();try {if (!executor.awaitTermination(90, TimeUnit.SECONDS)) {log.warn("线程池未在超时时间内关闭");}} catch (InterruptedException e) {log.error("等待线程池关闭时发生错误:{}", e.getMessage(), e);Thread.currentThread().interrupt();}log.info("generateMilitaryDescription 方法执行完成");}

3. 部分代码分析

这段代码防止重复生成数据存到Excel,用Set<String> existingVocabIds存储已在Excel中的数据(golaxy_vocab_id是唯一id)。

		// 用于存储已存在的golaxy_vocab_idSet<String> existingVocabIds = new HashSet<>();// 检查文件是否存在File file = new File(outputPath);if (file.exists()) {try (FileInputStream fileIn = new FileInputStream(file)) {workbook = new XSSFWorkbook(fileIn); // 读取现有文件sheet = workbook.getSheetAt(0); // 获取第一个工作表rowIndex[0] = sheet.getLastRowNum() + 1; // 计算新数据的起始行log.info("检测到现有文件,从第 {} 行开始追加", rowIndex[0]);// 将现有的 golaxy_node_id 和 golaxy_vocab_id 存入集合for (int i = 1; i <= sheet.getLastRowNum(); i++) { // 从第 1 行开始读取数据Row row = sheet.getRow(i);if (row != null) {Cell vocabIdCell = row.getCell(1); // 第 2 列为 golaxy_vocab_idif (vocabIdCell != null && vocabIdCell.getCellType() == CellType.STRING) {existingVocabIds.add(vocabIdCell.getStringCellValue());}}}} catch (IOException e) {log.error("读取现有文件时出错: {}", e.getMessage(), e);return;}}

线程的并发限制

		// 创建线程池,限制最高并发为 2ThreadPoolExecutor executor = new ThreadPoolExecutor(2,  // 核心线程数2,  // 最大线程数90,TimeUnit.SECONDS,new SynchronousQueue<>(), // 不允许任务排队,任务必须直接交给线程处理new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝的任务由调用线程执行);Semaphore semaphore = new Semaphore(2); // 限制并发任务数semaphore.acquire(); // 获取许可semaphore.release(); // 释放许可

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词