import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
public class ExcelUploadService {
private final WebClient webClient;
public ExcelUploadService(String thirdPartyBaseUrl) {
this.webClient = WebClient.builder()
.baseUrl(thirdPartyBaseUrl)
.build();
}
/**
* 上传Excel文件到第三方接口
* @param workbook Excel工作簿对象
* @param fileName 文件名
* @param additionalParams 额外的参数
* @param uploadUrl 上传接口URL
* @return 响应结果
*/
public Mono<String> uploadExcel(Workbook workbook, String fileName,
Map<String, String> additionalParams, String uploadUrl) {
try {
// 1. 将Workbook转换为字节数组
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] fileBytes = outputStream.toByteArray();
outputStream.close();
// 2. 构建Multipart表单数据
MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
// 添加Excel文件
bodyBuilder.part("file", fileBytes)
.filename(fileName)
.contentType(MediaType.APPLICATION_OCTET_STREAM);
// 添加其他参数
if (additionalParams != null) {
additionalParams.forEach((key, value) ->
bodyBuilder.part(key, value));
}
// 3. 构建请求体
var multipartBody = bodyBuilder.build();
// 4. 发送POST请求
return webClient.post()
.uri(uploadUrl)
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(multipartBody))
.retrieve()
.bodyToMono(String.class)
.doOnSuccess(response -> System.out.println("上传成功: " + response))
.doOnError(error -> System.err.println("上传失败: " + error.getMessage()));
} catch (IOException e) {
return Mono.error(new RuntimeException("Excel文件处理失败", e));
}
}
/**
* 上传Excel文件(简化版本,仅包含文件)
*/
public Mono<String> uploadExcel(Workbook workbook, String fileName, String uploadUrl) {
return uploadExcel(workbook, fileName, null, uploadUrl);
}
/**
* 使用DataBuffer方式上传(适用于大文件)
*/
public Mono<String> uploadExcelWithBuffer(Workbook workbook, String fileName,
Map<String, String> additionalParams, String uploadUrl) {
try {
// 将Workbook转换为字节数组
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] fileBytes = outputStream.toByteArray();
outputStream.close();
// 使用DataBuffer包装字节数组
DataBuffer dataBuffer = DataBufferUtils.wrap(fileBytes);
MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
bodyBuilder.part("file", dataBuffer)
.filename(fileName)
.contentType(MediaType.APPLICATION_OCTET_STREAM);
if (additionalParams != null) {
additionalParams.forEach((key, value) ->
bodyBuilder.part(key, value));
}
var multipartBody = bodyBuilder.build();
return webClient.post()
.uri(uploadUrl)
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(multipartBody))
.retrieve()
.bodyToMono(String.class);
} catch (IOException e) {
return Mono.error(new RuntimeException("Excel文件处理失败", e));
}
}
}