main
HuangHai 1 month ago
parent 91edaf6d38
commit 259bf1d701

@ -321,6 +321,23 @@
<artifactId>poi-scratchpad</artifactId> <artifactId>poi-scratchpad</artifactId>
<version>5.2.5</version> <version>5.2.5</version>
</dependency> </dependency>
<!-- CommonMark for Markdown parsing -->
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>0.21.0</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-gfm-tables</artifactId>
<version>0.21.0</version>
</dependency>
<dependency>
<groupId>org.commonmark</groupId>
<artifactId>commonmark-ext-heading-anchor</artifactId>
<version>0.21.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

@ -4,11 +4,20 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment; import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.commonmark.node.*;
import org.commonmark.parser.Parser;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* Word - Word * Word - Word
@ -105,52 +114,280 @@ public class WordGenerator {
} }
/** /**
* * - 使CommonMarkMarkdown
*/ */
private static void addAnalysisContent(XWPFDocument document, String analysisResult) { private static void addAnalysisContent(XWPFDocument document, String analysisResult) {
String[] lines = analysisResult.split("\n"); // 创建CommonMark解析器支持表格和标题锚点扩展
XWPFParagraph currentParagraph = null; List<org.commonmark.Extension> extensions = Arrays.asList(
XWPFRun currentRun = null; TablesExtension.create(),
HeadingAnchorExtension.create()
for (String line : lines) { );
if (line.trim().isEmpty()) { Parser parser = Parser.builder().extensions(extensions).build();
// 空行,创建新段落
document.createParagraph(); // 解析Markdown文档
currentParagraph = null; Node markdownDoc = parser.parse(analysisResult);
currentRun = null;
} else { // 遍历并处理所有节点
// 检查是否是标题行 processMarkdownNode(document, markdownDoc);
boolean isTitle = isTitle(line); }
if (currentParagraph == null) { /**
currentParagraph = document.createParagraph(); * MarkdownWord
currentRun = currentParagraph.createRun(); */
currentRun.setFontFamily("宋体"); private static void processMarkdownNode(XWPFDocument document, Node node) {
currentRun.setFontSize(12); Node child = node.getFirstChild();
while (child != null) {
if (child instanceof Heading) {
processHeading(document, (Heading) child);
} else if (child instanceof Paragraph) {
processParagraph(document, (Paragraph) child);
} else if (child instanceof BulletList) {
processBulletList(document, (BulletList) child);
} else if (child instanceof OrderedList) {
processOrderedList(document, (OrderedList) child);
} else if (child instanceof org.commonmark.ext.gfm.tables.TableBlock) {
processTable(document, (org.commonmark.ext.gfm.tables.TableBlock) child);
} else if (child instanceof BlockQuote) {
processBlockQuote(document, (BlockQuote) child);
} else if (child instanceof FencedCodeBlock || child instanceof IndentedCodeBlock) {
processCodeBlock(document, child);
}
child = child.getNext();
}
}
/**
*
*/
private static void processHeading(XWPFDocument document, Heading heading) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
String text = getTextContent(heading);
run.setText(text);
run.setBold(true);
run.setFontFamily("宋体");
// 根据标题级别设置字体大小
switch (heading.getLevel()) {
case 1:
run.setFontSize(18);
paragraph.setAlignment(ParagraphAlignment.CENTER);
break;
case 2:
run.setFontSize(16);
break;
case 3:
run.setFontSize(14);
break;
case 4:
run.setFontSize(13);
break;
default:
run.setFontSize(12);
break;
}
}
/**
*
*/
private static void processParagraph(XWPFDocument document, Paragraph para) {
XWPFParagraph paragraph = document.createParagraph();
processInlineNodes(paragraph, para.getFirstChild());
}
/**
*
*/
private static void processBulletList(XWPFDocument document, BulletList bulletList) {
Node listItem = bulletList.getFirstChild();
while (listItem != null) {
if (listItem instanceof ListItem) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("• " + getTextContent(listItem));
run.setFontSize(12);
run.setFontFamily("宋体");
}
listItem = listItem.getNext();
}
}
/**
*
*/
private static void processOrderedList(XWPFDocument document, OrderedList orderedList) {
Node listItem = orderedList.getFirstChild();
int counter = orderedList.getStartNumber();
while (listItem != null) {
if (listItem instanceof ListItem) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(counter + ". " + getTextContent(listItem));
run.setFontSize(12);
run.setFontFamily("宋体");
counter++;
}
listItem = listItem.getNext();
}
}
/**
*
*/
private static void processTable(XWPFDocument document, org.commonmark.ext.gfm.tables.TableBlock table) {
// 计算表格列数
int cols = 0;
Node firstRow = table.getFirstChild();
if (firstRow instanceof org.commonmark.ext.gfm.tables.TableHead) {
Node headerRow = firstRow.getFirstChild();
if (headerRow instanceof org.commonmark.ext.gfm.tables.TableRow) {
Node cell = headerRow.getFirstChild();
while (cell != null) {
cols++;
cell = cell.getNext();
} }
}
if (isTitle) { }
// 如果当前段落已有内容,创建新段落
String currentText = currentRun.getText(0); if (cols > 0) {
if (currentText != null && !currentText.isEmpty()) { XWPFTable wordTable = document.createTable();
currentParagraph = document.createParagraph();
currentRun = currentParagraph.createRun(); Node tableChild = table.getFirstChild();
currentRun.setFontFamily("宋体"); boolean isFirstRow = true;
} while (tableChild != null) {
currentRun.setText(line); if (tableChild instanceof org.commonmark.ext.gfm.tables.TableHead ||
currentRun.setBold(true); tableChild instanceof org.commonmark.ext.gfm.tables.TableBody) {
currentRun.setFontSize(14);
currentParagraph = null; // 强制下一行创建新段落 Node rowNode = tableChild.getFirstChild();
currentRun = null; while (rowNode != null) {
} else { if (rowNode instanceof org.commonmark.ext.gfm.tables.TableRow) {
// 普通内容 XWPFTableRow row;
String currentText = currentRun.getText(0); if (isFirstRow) {
if (currentText != null && !currentText.isEmpty()) { row = wordTable.getRow(0);
currentRun.addBreak(); isFirstRow = false;
} else {
row = wordTable.createRow();
}
Node cellNode = rowNode.getFirstChild();
int cellIndex = 0;
while (cellNode != null && cellIndex < cols) {
if (cellNode instanceof org.commonmark.ext.gfm.tables.TableCell) {
XWPFTableCell cell = row.getCell(cellIndex);
if (cell == null) {
cell = row.addNewTableCell();
}
cell.setText(getTextContent(cellNode));
cellIndex++;
}
cellNode = cellNode.getNext();
}
}
rowNode = rowNode.getNext();
} }
currentRun.setText(line);
currentRun.setFontSize(12);
} }
tableChild = tableChild.getNext();
}
}
}
/**
*
*/
private static void processBlockQuote(XWPFDocument document, BlockQuote blockQuote) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("" + getTextContent(blockQuote));
run.setFontSize(12);
run.setFontFamily("宋体");
run.setItalic(true);
}
/**
*
*/
private static void processCodeBlock(XWPFDocument document, Node codeBlock) {
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
String code;
if (codeBlock instanceof FencedCodeBlock) {
code = ((FencedCodeBlock) codeBlock).getLiteral();
} else {
code = ((IndentedCodeBlock) codeBlock).getLiteral();
}
run.setText(code);
run.setFontSize(10);
run.setFontFamily("Courier New");
// 设置背景色(如果支持)
}
/**
*
*/
private static void processInlineNodes(XWPFParagraph paragraph, Node node) {
while (node != null) {
if (node instanceof Text) {
XWPFRun run = paragraph.createRun();
run.setText(((Text) node).getLiteral());
run.setFontSize(12);
run.setFontFamily("宋体");
} else if (node instanceof StrongEmphasis) {
XWPFRun run = paragraph.createRun();
run.setText(getTextContent(node));
run.setBold(true);
run.setFontSize(12);
run.setFontFamily("宋体");
} else if (node instanceof Emphasis) {
XWPFRun run = paragraph.createRun();
run.setText(getTextContent(node));
run.setItalic(true);
run.setFontSize(12);
run.setFontFamily("宋体");
} else if (node instanceof Code) {
XWPFRun run = paragraph.createRun();
run.setText(((Code) node).getLiteral());
run.setFontSize(10);
run.setFontFamily("Courier New");
} else if (node instanceof Link) {
XWPFRun run = paragraph.createRun();
run.setText(getTextContent(node) + " (" + ((Link) node).getDestination() + ")");
run.setFontSize(12);
run.setFontFamily("宋体");
run.setColor("0000FF");
} else {
// 递归处理子节点
processInlineNodes(paragraph, node.getFirstChild());
}
node = node.getNext();
}
}
/**
*
*/
private static String getTextContent(Node node) {
StringBuilder text = new StringBuilder();
extractText(node, text);
return text.toString().trim();
}
/**
*
*/
private static void extractText(Node node, StringBuilder text) {
if (node instanceof Text) {
text.append(((Text) node).getLiteral());
} else if (node instanceof Code) {
text.append(((Code) node).getLiteral());
} else {
Node child = node.getFirstChild();
while (child != null) {
extractText(child, text);
child = child.getNext();
} }
} }
} }

@ -65,20 +65,20 @@ public class YunNanModel {
public String createAnalysisPrompt(String dataContent, String[] regions) { public String createAnalysisPrompt(String dataContent, String[] regions) {
String regionNames = String.join("和", regions); String regionNames = String.join("和", regions);
return "你是一位专业的教育数据分析专家,请基于以下数据对" + regionNames + "的教育资源配置情况进行深入对比分析。\n\n" + return "你是一位专业的教育数据分析专家,请基于以下数据对" + regionNames + "的教育资源配置情况进行深入对比分析。\n\n" +
"重要要求:请生成结构化的纯文本格式报告使用清晰的段落结构不要使用markdown语法。\n\n" + "重要要求:请生成结构化的Markdown格式报告使用标准的Markdown语法包括标题、列表、粗体等格式。\n\n" +
"请按照以下结构进行分析并生成专业的分析报告:\n\n" + "请按照以下结构进行分析并生成专业的分析报告:\n\n" +
"1. 执行摘要\n" + "## 1. 执行摘要\n" +
" 简要概述两州教育资源配置的整体情况和主要发现\n\n" + "简要概述两州教育资源配置的整体情况和主要发现\n\n" +
"2. 数据概览\n" + "## 2. 数据概览\n" +
" 两州基本教育数据对比和关键指标汇总\n\n" + "两州基本教育数据对比和关键指标汇总\n\n" +
"3. 详细对比分析\n" + "## 3. 详细对比分析\n" +
" 教育资源配置水平对比、发展趋势分析、优势与不足分析\n\n" + "教育资源配置水平对比、发展趋势分析、优势与不足分析\n\n" +
"4. 问题识别\n" + "## 4. 问题识别\n" +
" 存在的主要问题和资源配置不均衡情况\n\n" + "存在的主要问题和资源配置不均衡情况\n\n" +
"5. 建议与对策\n" + "## 5. 建议与对策\n" +
" 针对性改进建议和资源优化配置方案\n\n" + "针对性改进建议和资源优化配置方案\n\n" +
"6. 结论\n" + "## 6. 结论\n" +
" 总体评价和未来发展方向\n\n" + "总体评价和未来发展方向\n\n" +
"请确保分析客观、专业,数据引用准确,建议具有可操作性。\n\n" + "请确保分析客观、专业,数据引用准确,建议具有可操作性。\n\n" +
"=== 原始数据 ===\n" + dataContent; "=== 原始数据 ===\n" + dataContent;
} }

@ -148,6 +148,7 @@ public class CallDeepSeek {
if (saveToFile && outputPath != null) { if (saveToFile && outputPath != null) {
FileUtil.writeString(responseContent, new File(outputPath), "UTF-8"); FileUtil.writeString(responseContent, new File(outputPath), "UTF-8");
listener.onComplete("内容已成功保存到" + outputPath); listener.onComplete("内容已成功保存到" + outputPath);
System.out.println("内容已成功保存到" + outputPath);
} else { } else {
listener.onComplete(responseContent); listener.onComplete(responseContent);
} }

Loading…
Cancel
Save