快速对接ppt生成功能

我对接讯飞的ppt生成,整个对接流程非常简单,我这里是把他接入到系统中所以业务代码隐藏了部分

1.下载相关demo文档进行参考

demo
讯飞开放平台

2.根据自己的业务写代码

java 复制代码
    public static final String appid = ""; //这里填写APPID
    public static final String apiSecret = ""; //这里填写Secret
    public static final String apiKey = ""; //这里填写Key
    @Value("${file.upload}")
    private String filePath;
public void getPPT(AiSetDto aiSetDto, HttpServletRequest request, HttpServletResponse response) throws Exception {
      
        AsyncContext asyncContext = request.startAsync(request, response);
        asyncContext.setTimeout(0); // 设置超时时间为0,表示无限期等待

        long timestamp = System.currentTimeMillis() / 1000;
        String ts = String.valueOf(timestamp);

        ApiAuthAlgorithm auth = new ApiAuthAlgorithm();
        String signature = auth.getSignature(appid, apiSecret, timestamp);
        // 建立链接
        ApiClient client = new ApiClient("https://zwapi.xfyun.cn/api/ppt/v2");

        asyncContext.start(() -> {
            try (OutputStream outputStream = response.getOutputStream()) {
                //用户输入的内容
                String content = aiSetDto.getMessages().get(aiSetDto.getMessages().size() - 1).getContent();
                String resp;
                if (content.length() < 200) {//小于200字,通过大纲生成。
                    //用户输入的字太少就根据内容生成大纲在生成PPT
                    String outlineResp = client.createOutline(appid, ts, signature, content);
                    System.out.println("大纲" + outlineResp);
                    XFPPTResponseDto outlineResponse = JSON.parseObject(outlineResp, XFPPTResponseDto.class);
                    String outline = outlineResponse.getData().getOutline();
                    //PPT生成 (通过大纲生成PPT)
                    resp = client.createPptByOutline(appid, ts, signature, outline);
                } else {
                    //PPT生成 (直接生成PPT)
                    resp = client.createPptByOutline(appid, ts, signature, content);
                }
                System.out.println("ppt返回信息" + resp);
                // 解析返回结果
                XFPPTResponseDto pptResponse = JSON.parseObject(resp, XFPPTResponseDto.class);
                String sid = pptResponse.getData().getSid();
                System.out.println("sid=" + sid);//sid用于获取下载连接

                // 检查进度
                String progressResult = client.checkProgress(appid, ts, signature, sid);
                XFPPTURLDto urlDto = JSON.parseObject(progressResult, XFPPTURLDto.class);
                if (!"成功".equals(urlDto.getDesc())) { // 生成失败
                    outputStream.write(urlDto.getDesc().getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    return;
                }

                while ("building".equals(urlDto.getData().getPptStatus())) {//加载完成后出来
                    if (isStopped.get()) { // 如果用户停止生成
                        break;
                    }
                    Thread.sleep(3000); //注:该接口设置限流,三秒访问一次 (因为是异步里面所以让它等应该没事)
                    progressResult = client.checkProgress(appid, ts, signature, sid);
                    double v = CommonUtil.calculateCompletionPercentage(urlDto.getData().getTotalPages(), urlDto.getData().getDonePages());//计算百分比
//                    System.out.println("生成进度:" + v + "%");
                    outputStream.write(("生成进度:" + v + "%").getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    urlDto = JSON.parseObject(progressResult, XFPPTURLDto.class);
                }
                if (isStopped.get()) { // 如果用户停止生成
                    outputStream.write("用户已停止生成".getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    return;
                }
                if ("build_failed".equals(urlDto.getData().getPptStatus())) {
                    outputStream.write("PPT生成失败".getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    return;
                }
                System.out.println(progressResult);
                String pptUrl = urlDto.getData().getPptUrl();
                String savePath = filePath + "generate";//生成ppt路径
                String fileName = CommonUtil.GenerateRandomName() + ".ppt";//生成ppt名称
                String saveFilePath = savePath + File.separator + fileName;

                try (InputStream in = new URL(pptUrl).openStream()) {
                    Files.copy(in, Paths.get(saveFilePath), StandardCopyOption.REPLACE_EXISTING);
                    System.out.println("文件成功下载到:" + saveFilePath);
                    outputStream.write(("generate/" + fileName).getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                } catch (Exception e) {
                    outputStream.write("PPT传输异常".getBytes(StandardCharsets.UTF_8));
                    outputStream.flush();
                    System.err.println("下载过程中出现错误: " + e.getMessage());
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                asyncContext.complete();
                StopGeneratingUtil.remove(requestId); // 移除停止标志
            }
        });
    }

计算百分比方法

java 复制代码
    /**
     * 计算完成百分比
     *
     * @param totalPages 总页数
     * @param donePages  已完成页数
     * @return 完成百分比
     */
    public static double calculateCompletionPercentage(int totalPages, int donePages) {
        if (totalPages == 0) {
            return 0.0;
        }
        double percentage = ((double) donePages / totalPages) * 100;

        // 使用 BigDecimal 设置保留两位小数并四舍五入
        BigDecimal bd = new BigDecimal(percentage);
        bd = bd.setScale(2, RoundingMode.HALF_UP); // 四舍五入到两位小数
        return bd.doubleValue();
    }

添加讯飞的两个工具类

java 复制代码
import org.apache.hc.client5.http.utils.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class ApiAuthAlgorithm {

    /**
     * Gets the signature for the given appId and secret.
     *
     * @param appId  The appId used as a key for the signature.
     * @param apiSecret The secret key used for the signature.
     * @param ts     The timestamp.
     * @return The generated signature.
     */
    public String getSignature(String appId, String apiSecret, long ts) {
        try {
            String auth = md5(appId + ts);
            return hmacSHA1Encrypt(auth, apiSecret);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            // Log the exception for debugging
            e.printStackTrace();
            return null;
        }
    }

    /**
     * HMAC SHA1 encryption.
     *
     * @param encryptText The text to be encrypted.
     * @param encryptKey  The encryption key.
     * @return The encrypted string.
     * @throws NoSuchAlgorithmException If the algorithm is not available.
     * @throws InvalidKeyException      If the key is invalid.
     */
    private String hmacSHA1Encrypt(String encryptText, String encryptKey)
            throws NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec keySpec = new SecretKeySpec(
                encryptKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");

        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(keySpec);
        byte[] result = mac.doFinal(encryptText.getBytes(StandardCharsets.UTF_8));

        return Base64.encodeBase64String(result);
    }

    /**
     * Generates MD5 hash of the given text.
     *
     * @param text The text to be hashed.
     * @return The MD5 hash of the text.
     * @throws NoSuchAlgorithmException If the MD5 algorithm is not available.
     */
    private String md5(String text) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(text.getBytes(StandardCharsets.UTF_8));

        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
java 复制代码
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class ApiClient {

    private static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";
    private final static OkHttpClient client = new OkHttpClient().newBuilder()
            .connectionPool(new ConnectionPool(100, 5, TimeUnit.MINUTES))
            .readTimeout(60 * 10, TimeUnit.SECONDS)
            .build();
    private static final String ERROR_MESSAGE = "Unexpected code: ";
    private final String baseUrl;

    public ApiClient(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getTemplateList(String appId, String timestamp, String signature) throws IOException {
        validateParameters(appId, timestamp, signature);

        //注意:请求体不能为空,至少有一项
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("style", "商务");
        jsonObject.put("pageSize", "10");
        RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get(MEDIA_TYPE_JSON));

        Request request = buildPostRequest(baseUrl + "/template/list", appId, timestamp, signature, body);
        return executeRequest(request);
    }

    public String createOutline(String appId, String timestamp, String signature, String query) throws IOException {
        validateParameters(appId, timestamp, signature, query);

        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        builder.addFormDataPart("query", query);
        RequestBody body = builder.build();

        Request request = buildPostRequest(baseUrl + "/createOutline", appId, timestamp, signature, body);
        return executeRequest(request);
    }

    public String createOutlineByDoc(String appId, String timestamp, String signature, File file) throws IOException {
        validateParameters(appId, timestamp, signature);

        MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
        try {
            body.addFormDataPart("file", file.getName(), RequestBody.create(null, file));
            body.addFormDataPart("fileName", file.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        RequestBody requestBody = body.build();

        Request request = new Request.Builder()
                .url(baseUrl + "/createOutlineByDoc")
                .addHeader("appId", appId)
                .addHeader("timestamp", timestamp)
                .addHeader("signature", signature)
                //.addHeader("Content-Type", "multipart/form-data")
                .post(requestBody)
                .build();
        return executeRequest(request);
    }

    public String create(String appId, String timestamp, String signature,File file) throws IOException {
        validateParameters(appId, timestamp, signature);

        MultipartBody.Builder builder = new MultipartBody.Builder();

        builder.setType(MultipartBody.FORM);
        builder.addFormDataPart("file", file.getName(),
                RequestBody.create(MediaType.parse("multipart/form-data"), file));
        builder.addFormDataPart("fileName", file.getName());
        RequestBody body = builder.build();

        Request request = buildPostRequest(baseUrl + "/create", appId, timestamp, signature, body);
        return executeRequest(request);
    }


    public String createPptByOutline(String appId, String ts, String signature,String outline) throws IOException {
        validateParameters(appId, ts, signature);
        JSONObject jsonObject = new JSONObject();

        JSONObject outlineJson = JSONObject.parseObject(outline);
        jsonObject.put("outline", outlineJson);
        jsonObject.put("query", "test");
        RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get(MEDIA_TYPE_JSON));

        Request request = buildPostRequest(baseUrl + "/createPptByOutline", appId, ts, signature, body);
        return executeRequest(request);
    }

    public String checkProgress(String appId, String timestamp, String signature, String sid) throws IOException {
        validateParameters(appId, timestamp, signature, sid);

        HttpUrl url = HttpUrl.parse(baseUrl+"/progress").newBuilder()
                .addQueryParameter("sid", sid)
                .build();

        Request request = buildGetRequest(url.toString(), appId, timestamp, signature);
        return executeRequest(request);
    }


    private Request buildPostRequest(String url, String appId, String timestamp, String signature, RequestBody body) {
        return new Request.Builder()
                .url(url)
                .addHeader("appId", appId)
                .addHeader("timestamp", timestamp)
                .addHeader("signature", signature)
                .post(body)
                .build();
    }

    private Request buildGetRequest(String url, String appId, String timestamp, String signature) {
        return new Request.Builder()
                .url(url)
                .addHeader("appId", appId)
                .addHeader("timestamp", timestamp)
                .addHeader("signature", signature)
                .get()
                .build();
    }

    private String executeRequest(Request request) throws IOException {
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.out.println(response.body().string());
                throw new IOException(ERROR_MESSAGE + response);
            }
            return response.body().string();
        }
    }

    private void validateParameters(String... params) {
        for (String param : params) {
            if (param == null || param.isEmpty()) {
                throw new IllegalArgumentException("Parameter cannot be null or empty");
            }
        }
    }


}
相关推荐
xyliiiiiL1 小时前
从责任链模式聊到aware接口
java·开发语言
影子24014 小时前
Navicat导出mysql数据库表结构说明到excel、word,单表导出方式记录
数据库·mysql·excel
码农老起4 小时前
与Aspose.pdf类似的jar库分享
java·pdf·jar
程序猿小D4 小时前
第三百八十九节 JavaFX教程 - JavaFX WebEngine
java·eclipse·intellij-idea·vr·javafx
java_heartLake4 小时前
PostgreSQL15深度解析(从15.0-15.12)
数据库·postgresql
self-discipline6346 小时前
【Java】Java核心知识点与相应面试技巧(七)——类与对象(二)
java·开发语言·面试
wei3872452326 小时前
java笔记02
java·开发语言·笔记
nuc-1276 小时前
sqli-labs学习记录8
数据库·学习·sqli-labs
zjj5877 小时前
Docker使用ubuntu
java·docker·eureka
士别三日&&当刮目相看7 小时前
JAVA学习*简单的代理模式
java·学习·代理模式