diff --git a/pom.xml b/pom.xml index 49f67817..4d30fad2 100644 --- a/pom.xml +++ b/pom.xml @@ -305,6 +305,22 @@ 0.30.1 + + + org.apache.poi + poi + 5.2.5 + + + org.apache.poi + poi-ooxml + 5.2.5 + + + org.apache.poi + poi-scratchpad + 5.2.5 + diff --git a/src/main/java/com/dsideal/base/Tools/AiGenerate.java b/src/main/java/com/dsideal/base/Tools/AiGenerate.java index 60cdc8d1..1902d510 100644 --- a/src/main/java/com/dsideal/base/Tools/AiGenerate.java +++ b/src/main/java/com/dsideal/base/Tools/AiGenerate.java @@ -7,10 +7,14 @@ import com.dsideal.base.Tools.Util.CallDeepSeek; import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil; import com.jfinal.plugin.activerecord.Db; import com.jfinal.plugin.activerecord.Record; -import cn.hutool.core.io.FileUtil; import cn.hutool.json.JSONUtil; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.apache.poi.xwpf.usermodel.ParagraphAlignment; -import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @@ -27,124 +31,209 @@ public class AiGenerate { // 查询教育资源配置发展预测相关表 String sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dataease' AND TABLE_NAME LIKE 'excel_报告-教育资源配置发展预测%';"; List tableList = Db.find(sql); - - String[] biJiao = new String[]{"文山州", "楚雄州"}; + + String[] biJiao = new String[]{"文山州", "楚雄州", "昆明市"}; StringBuilder dataContent = new StringBuilder(); - + // 收集两个州的数据 - dataContent.append("# 教育资源配置发展预测数据对比分析\n\n"); - dataContent.append("## 对比州市:").append(String.join(" vs ", biJiao)).append("\n\n"); - + dataContent.append("教育资源配置发展预测数据对比分析\n\n"); + dataContent.append("对比州市:").append(String.join(" vs ", biJiao)).append("\n\n"); + for (Record record : tableList) { String tableName = record.getStr("TABLE_NAME"); - dataContent.append("### 数据表:").append(tableName).append("\n"); - + dataContent.append("数据表:").append(tableName).append("\n"); + for (int j = 0; j < biJiao.length; j++) { sql = "select * from `" + tableName + "` where `行政区划`=?"; List listContent = Db.use(DataEaseModel.DB_NAME).find(sql, biJiao[j]); - + if (!listContent.isEmpty()) { - dataContent.append("\n#### ").append(biJiao[j]).append("数据:\n"); + dataContent.append("\n").append(biJiao[j]).append("数据:\n"); for (Record dataRecord : listContent) { dataContent.append(JSONUtil.toJsonPrettyStr(dataRecord.getColumns())).append("\n"); } } else { - dataContent.append("\n#### ").append(biJiao[j]).append(":无相关数据\n"); + dataContent.append("\n").append(biJiao[j]).append(":无相关数据\n"); } } - dataContent.append("\n---\n\n"); + dataContent.append("\n----------------------------------------\n\n"); } - + // 构建分析提示词 String analysisPrompt = createAnalysisPrompt(dataContent.toString()); - + // 生成输出文件路径 String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String outputPath = "教育资源对比分析报告_" + timestamp + ".docx"; - + System.out.println("开始调用DeepSeek进行数据分析..."); - + // 调用DeepSeek进行分析 CallDeepSeek.callDeepSeekStream(analysisPrompt, new CallDeepSeek.SSEListener() { private StringBuilder fullResponse = new StringBuilder(); - + @Override public void onData(String data) { System.out.print(data); System.out.flush(); fullResponse.append(data); } - + @Override public void onComplete(String response) { System.out.println("\n\n=== 分析完成 ==="); - + try { - // 将分析结果保存为Word文档格式的内容 - String wordContent = convertToWordFormat(fullResponse.toString()); - FileUtil.writeString(wordContent, new File(outputPath), "UTF-8"); + // 使用Apache POI生成Word文档 + generateWordDocument(fullResponse.toString(), outputPath); System.out.println("分析报告已保存到: " + outputPath); } catch (Exception e) { System.err.println("保存文件时出错: " + e.getMessage()); e.printStackTrace(); } } - + @Override public void onError(String error) { System.err.println("DeepSeek分析出错: " + error); } }); } - + /** * 创建分析提示词 */ private static String createAnalysisPrompt(String dataContent) { return "你是一位专业的教育数据分析专家,请基于以下数据对文山州和楚雄州的教育资源配置情况进行深入对比分析。\n\n" + + "重要要求:请生成结构化的纯文本格式报告,使用清晰的段落结构,不要使用markdown语法。\n\n" + "请按照以下结构进行分析并生成专业的分析报告:\n\n" + - "1. **执行摘要**\n" + - " - 简要概述两州教育资源配置的整体情况\n" + - " - 主要发现和结论\n\n" + - "2. **数据概览**\n" + - " - 两州基本教育数据对比\n" + - " - 关键指标汇总\n\n" + - "3. **详细对比分析**\n" + - " - 教育资源配置水平对比\n" + - " - 发展趋势分析\n" + - " - 优势与不足分析\n\n" + - "4. **问题识别**\n" + - " - 存在的主要问题\n" + - " - 资源配置不均衡情况\n\n" + - "5. **建议与对策**\n" + - " - 针对性改进建议\n" + - " - 资源优化配置方案\n\n" + - "6. **结论**\n" + - " - 总体评价\n" + - " - 未来发展方向\n\n" + + "1. 执行摘要\n" + + " 简要概述两州教育资源配置的整体情况和主要发现\n\n" + + "2. 数据概览\n" + + " 两州基本教育数据对比和关键指标汇总\n\n" + + "3. 详细对比分析\n" + + " 教育资源配置水平对比、发展趋势分析、优势与不足分析\n\n" + + "4. 问题识别\n" + + " 存在的主要问题和资源配置不均衡情况\n\n" + + "5. 建议与对策\n" + + " 针对性改进建议和资源优化配置方案\n\n" + + "6. 结论\n" + + " 总体评价和未来发展方向\n\n" + "请确保分析客观、专业,数据引用准确,建议具有可操作性。\n\n" + "=== 原始数据 ===\n" + dataContent; } - + /** - * 将分析结果转换为Word文档格式 + * 使用Apache POI生成Word文档 */ - private static String convertToWordFormat(String analysisResult) { - StringBuilder wordContent = new StringBuilder(); - - // 添加文档头部 - wordContent.append("文山州与楚雄州教育资源配置对比分析报告\n"); - wordContent.append("=".repeat(50)).append("\n\n"); - wordContent.append("生成时间:").append(new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date())).append("\n"); - wordContent.append("分析工具:DeepSeek AI\n\n"); - - // 添加分析内容 - wordContent.append(analysisResult); - - // 添加文档尾部 - wordContent.append("\n\n").append("=".repeat(50)).append("\n"); - wordContent.append("报告结束\n"); - - return wordContent.toString(); + private static void generateWordDocument(String analysisResult, String outputPath) throws Exception { + XWPFDocument document = new XWPFDocument(); + + try { + // 添加标题 + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(ParagraphAlignment.CENTER); + XWPFRun titleRun = titleParagraph.createRun(); + titleRun.setText("文山州与楚雄州教育资源配置对比分析报告"); + titleRun.setBold(true); + titleRun.setFontSize(18); + titleRun.setFontFamily("宋体"); + + // 添加空行 + document.createParagraph(); + + // 添加生成信息 + XWPFParagraph infoParagraph = document.createParagraph(); + XWPFRun infoRun = infoParagraph.createRun(); + infoRun.setText("生成时间:" + new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date())); + infoRun.setFontSize(12); + infoRun.setFontFamily("宋体"); + + XWPFRun toolRun = infoParagraph.createRun(); + toolRun.addBreak(); + toolRun.setText("分析工具:DeepSeek AI"); + toolRun.setFontSize(12); + toolRun.setFontFamily("宋体"); + + // 添加分隔线 + XWPFParagraph separatorParagraph = document.createParagraph(); + XWPFRun separatorRun = separatorParagraph.createRun(); + separatorRun.setText("=".repeat(50)); + separatorRun.setFontSize(10); + + // 添加空行 + document.createParagraph(); + + // 处理分析内容 + String[] lines = analysisResult.split("\n"); + XWPFParagraph currentParagraph = null; + XWPFRun currentRun = null; + + for (String line : lines) { + if (line.trim().isEmpty()) { + // 空行,创建新段落 + document.createParagraph(); + currentParagraph = null; + currentRun = null; + } else { + // 检查是否是标题行(数字开头或特殊格式) + boolean isTitle = line.matches("^\\d+\\..+") || + line.matches("^[一二三四五六七八九十]+、.+") || + line.trim().matches("^(执行摘要|数据概览|详细对比分析|问题识别|建议与对策|结论).*"); + + if (currentParagraph == null) { + currentParagraph = document.createParagraph(); + currentRun = currentParagraph.createRun(); + currentRun.setFontFamily("宋体"); + currentRun.setFontSize(12); + } + + if (isTitle) { + // 如果当前段落已有内容,创建新段落 + String currentText = currentRun.getText(0); + if (currentText != null && !currentText.isEmpty()) { + currentParagraph = document.createParagraph(); + currentRun = currentParagraph.createRun(); + currentRun.setFontFamily("宋体"); + } + currentRun.setText(line); + currentRun.setBold(true); + currentRun.setFontSize(14); + currentParagraph = null; // 强制下一行创建新段落 + currentRun = null; + } else { + // 普通内容 + String currentText = currentRun.getText(0); + if (currentText != null && !currentText.isEmpty()) { + currentRun.addBreak(); + } + currentRun.setText(line); + currentRun.setFontSize(12); + } + } + } + + // 添加结尾 + XWPFParagraph endParagraph = document.createParagraph(); + endParagraph.createRun().addBreak(); + XWPFRun endSeparatorRun = endParagraph.createRun(); + endSeparatorRun.setText("=".repeat(50)); + endSeparatorRun.setFontSize(10); + + XWPFRun endRun = endParagraph.createRun(); + endRun.addBreak(); + endRun.setText("报告结束"); + endRun.setFontSize(12); + endRun.setFontFamily("宋体"); + endRun.setBold(true); + + // 保存文档 + try (FileOutputStream out = new FileOutputStream(outputPath)) { + document.write(out); + } + + } finally { + document.close(); + } } } diff --git a/教育资源对比分析报告_20250613_153044.docx b/教育资源对比分析报告_20250613_153044.docx new file mode 100644 index 00000000..6282480c Binary files /dev/null and b/教育资源对比分析报告_20250613_153044.docx differ