|
|
@ -4,12 +4,9 @@ import com.alibaba.fastjson.JSONObject;
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
import java.io.*;
|
|
|
|
|
|
|
|
import java.net.HttpURLConnection;
|
|
|
|
import java.net.HttpURLConnection;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* PPT生成器 - 负责生成分析报告的PPT演示文稿
|
|
|
|
* PPT生成器 - 负责生成分析报告的PPT演示文稿
|
|
|
@ -17,43 +14,47 @@ import java.util.Date;
|
|
|
|
public class PptGenerator {
|
|
|
|
public class PptGenerator {
|
|
|
|
|
|
|
|
|
|
|
|
private static final String PPT_API_URL = "https://open.docmee.cn/api/ppt/generatePptx";
|
|
|
|
private static final String PPT_API_URL = "https://open.docmee.cn/api/ppt/generatePptx";
|
|
|
|
// 指定保存目录
|
|
|
|
|
|
|
|
private static final String SAVE_DIRECTORY = "D:\\dsWork\\YunNanDsBase\\WebRoot\\upload";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 生成PPT演示文稿
|
|
|
|
* 构建PPT提示词
|
|
|
|
* @param analysisContent 分析内容(与Word文档相同的内容)
|
|
|
|
* @param dataContent 数据内容
|
|
|
|
* @param regions 对比地区
|
|
|
|
* @param regionName 地区名称
|
|
|
|
|
|
|
|
* @return PPT生成提示词
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static String buildPptPrompt(String dataContent, String regionName) {
|
|
|
|
|
|
|
|
return String.format(
|
|
|
|
|
|
|
|
"请根据以下数据内容,生成一个适合制作PPT的大纲,要求:\n\n" +
|
|
|
|
|
|
|
|
"1. 生成标准的Markdown格式大纲,用于PPT制作\n" +
|
|
|
|
|
|
|
|
"2. 大纲应该包含清晰的章节结构,每个章节都有明确的标题\n" +
|
|
|
|
|
|
|
|
"3. 每个章节下应该有3-5个要点,适合在PPT幻灯片中展示\n" +
|
|
|
|
|
|
|
|
"4. 重点突出数据对比和分析结论\n" +
|
|
|
|
|
|
|
|
"5. 大纲应该逻辑清晰,便于制作专业的演示文稿\n" +
|
|
|
|
|
|
|
|
"6. 包含以下主要部分:\n" +
|
|
|
|
|
|
|
|
" - 概述与背景\n" +
|
|
|
|
|
|
|
|
" - 数据对比分析\n" +
|
|
|
|
|
|
|
|
" - 关键发现\n" +
|
|
|
|
|
|
|
|
" - 结论与建议\n\n" +
|
|
|
|
|
|
|
|
"地区:%s\n\n" +
|
|
|
|
|
|
|
|
"数据内容:\n%s",
|
|
|
|
|
|
|
|
regionName, dataContent
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 直接从Markdown内容生成PPT(不调用DeepSeek)
|
|
|
|
|
|
|
|
* @param markdownContent PPT大纲的Markdown内容(由DeepSeek生成)
|
|
|
|
* @param token API访问令牌
|
|
|
|
* @param token API访问令牌
|
|
|
|
* @return 本地PPT文件路径
|
|
|
|
* @return PPT文件下载URL
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static String generatePptPresentation(String analysisContent, String[] regions, String token) {
|
|
|
|
public static String generatePptFromMarkdown(String markdownContent, String token) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 确保保存目录存在
|
|
|
|
// 直接使用传入的markdown内容调用docmee API生成PPT
|
|
|
|
File saveDir = new File(SAVE_DIRECTORY);
|
|
|
|
|
|
|
|
if (!saveDir.exists()) {
|
|
|
|
|
|
|
|
saveDir.mkdirs();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将分析内容转换为Markdown格式
|
|
|
|
|
|
|
|
String markdownContent = convertToMarkdown(analysisContent, regions);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用docmee API生成PPT
|
|
|
|
|
|
|
|
String pptFileUrl = callDocmeeApi(markdownContent, token);
|
|
|
|
String pptFileUrl = callDocmeeApi(markdownContent, token);
|
|
|
|
|
|
|
|
|
|
|
|
if (pptFileUrl != null && !pptFileUrl.trim().isEmpty()) {
|
|
|
|
if (pptFileUrl != null && !pptFileUrl.trim().isEmpty()) {
|
|
|
|
System.out.println("PPT生成成功!");
|
|
|
|
System.out.println("PPT生成成功!");
|
|
|
|
System.out.println("PPT文件下载地址: " + pptFileUrl);
|
|
|
|
System.out.println("PPT文件下载地址: " + pptFileUrl);
|
|
|
|
|
|
|
|
return pptFileUrl;
|
|
|
|
// 下载PPT文件到本地
|
|
|
|
|
|
|
|
String localFilePath = downloadPptFile(pptFileUrl, regions);
|
|
|
|
|
|
|
|
if (localFilePath != null) {
|
|
|
|
|
|
|
|
System.out.println("PPT文件已下载到: " + localFilePath);
|
|
|
|
|
|
|
|
return localFilePath;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
System.err.println("PPT文件下载失败");
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
System.err.println("PPT生成失败");
|
|
|
|
System.err.println("PPT生成失败");
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
@ -65,120 +66,19 @@ public class PptGenerator {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 下载PPT文件到本地
|
|
|
|
|
|
|
|
* @param fileUrl PPT文件下载URL
|
|
|
|
|
|
|
|
* @param regions 对比地区
|
|
|
|
|
|
|
|
* @return 本地文件路径
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static String downloadPptFile(String fileUrl, String[] regions) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 生成本地文件名
|
|
|
|
|
|
|
|
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
|
|
|
|
|
|
|
|
String fileName = generateReportTitle(regions).replace("教育资源配置对比分析报告", "教育资源对比分析报告") + "_" + timestamp + ".pptx";
|
|
|
|
|
|
|
|
String localFilePath = SAVE_DIRECTORY + File.separator + fileName;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 下载文件
|
|
|
|
|
|
|
|
URL url = new URL(fileUrl);
|
|
|
|
|
|
|
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
|
|
|
|
|
connection.setRequestMethod("GET");
|
|
|
|
|
|
|
|
connection.setConnectTimeout(30000); // 30秒连接超时
|
|
|
|
|
|
|
|
connection.setReadTimeout(60000); // 60秒读取超时
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int responseCode = connection.getResponseCode();
|
|
|
|
|
|
|
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
|
|
|
|
|
|
try (InputStream inputStream = connection.getInputStream();
|
|
|
|
|
|
|
|
FileOutputStream outputStream = new FileOutputStream(localFilePath)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] buffer = new byte[4096];
|
|
|
|
|
|
|
|
int bytesRead;
|
|
|
|
|
|
|
|
long totalBytesRead = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
|
|
|
|
|
outputStream.write(buffer, 0, bytesRead);
|
|
|
|
|
|
|
|
totalBytesRead += bytesRead;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("文件下载完成,大小: " + totalBytesRead + " 字节");
|
|
|
|
|
|
|
|
return localFilePath;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
System.err.println("下载失败,HTTP状态码: " + responseCode);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
System.err.println("下载PPT文件时出错: " + e.getMessage());
|
|
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 将分析内容转换为Markdown格式
|
|
|
|
* 生成PPT演示文稿(保留原方法以兼容其他调用)
|
|
|
|
* @param analysisContent 分析内容
|
|
|
|
* @param markdownContent PPT大纲的Markdown内容(由DeepSeek生成)
|
|
|
|
* @param regions 对比地区
|
|
|
|
* @param regions 对比地区
|
|
|
|
* @return Markdown格式的内容
|
|
|
|
* @param token API访问令牌
|
|
|
|
*/
|
|
|
|
* @return PPT文件下载URL
|
|
|
|
private static String convertToMarkdown(String analysisContent, String[] regions) {
|
|
|
|
|
|
|
|
StringBuilder markdown = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加标题
|
|
|
|
|
|
|
|
String title = generateReportTitle(regions);
|
|
|
|
|
|
|
|
markdown.append("# ").append(title).append("\n\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理分析内容
|
|
|
|
|
|
|
|
String[] lines = analysisContent.split("\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (String line : lines) {
|
|
|
|
|
|
|
|
if (line.trim().isEmpty()) {
|
|
|
|
|
|
|
|
markdown.append("\n");
|
|
|
|
|
|
|
|
} else if (isTitle(line)) {
|
|
|
|
|
|
|
|
// 根据标题级别添加Markdown标题
|
|
|
|
|
|
|
|
if (line.matches("^\\d+\\..+")) {
|
|
|
|
|
|
|
|
markdown.append("## ").append(line).append("\n\n");
|
|
|
|
|
|
|
|
} else if (line.matches("^\\d+\\.\\d+.+")) {
|
|
|
|
|
|
|
|
markdown.append("### ").append(line).append("\n\n");
|
|
|
|
|
|
|
|
} else if (line.matches("^\\d+\\.\\d+\\.\\d+.+")) {
|
|
|
|
|
|
|
|
markdown.append("#### ").append(line).append("\n\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
markdown.append("## ").append(line).append("\n\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 普通内容,处理列表项
|
|
|
|
|
|
|
|
if (line.trim().startsWith("-") || line.trim().startsWith("•")) {
|
|
|
|
|
|
|
|
markdown.append("- ").append(line.trim().substring(1).trim()).append("\n");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
markdown.append(line).append("\n\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return markdown.toString();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 生成报告标题
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static String generateReportTitle(String[] regions) {
|
|
|
|
|
|
|
|
if (regions != null && regions.length >= 2) {
|
|
|
|
|
|
|
|
return String.join("与", regions) + "教育资源配置对比分析报告";
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return "教育资源配置对比分析报告";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 判断是否为标题行
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private static boolean isTitle(String line) {
|
|
|
|
public static String generatePptPresentation(String markdownContent, String[] regions, String token) {
|
|
|
|
return line.matches("^\\d+\\..+") ||
|
|
|
|
return generatePptFromMarkdown(markdownContent, token);
|
|
|
|
line.matches("^\\d+\\.\\d+.+") ||
|
|
|
|
|
|
|
|
line.matches("^\\d+\\.\\d+\\.\\d+.+") ||
|
|
|
|
|
|
|
|
line.trim().matches("^(执行摘要|数据概览|详细对比分析|问题识别|建议与对策|结论).*");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 调用docmee API生成PPT
|
|
|
|
* 调用docmee API生成PPT
|
|
|
|
* @param markdownContent Markdown内容
|
|
|
|
* @param markdownContent Markdown内容
|
|
|
|