import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
public class ExcelUploadService {
private final WebClient webClient;
public ExcelUploadService(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.build();
}
/**
* 上传Excel文件到第三方接口
* @param workbook Excel工作簿对象
* @param fileName 文件名
* @param uploadUrl 上传接口URL
* @return 上传结果
*/
public Mono<String> uploadExcelFile(org.apache.poi.ss.usermodel.Workbook workbook,
String fileName, String uploadUrl) {
return Mono.fromCallable(() -> {
// 将Workbook转换为字节数组
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] fileBytes = outputStream.toByteArray();
outputStream.close();
return fileBytes;
})
.flatMap(fileBytes -> {
// 创建Multipart表单数据
var multipartBody = BodyInserters
.fromMultipartData("file", new ByteArrayInputStream(fileBytes))
.with("filename", fileName);
return webClient.post()
.uri(uploadUrl)
.bodyValue(multipartBody)
.retrieve()
.bodyToMono(String.class)
.onErrorMap(WebClientResponseException.class, ex ->
new RuntimeException("上传失败: " + ex.getResponseBodyAsString(), ex));
});
}
/**
* 另一种实现方式:使用FormData
*/
public Mono<String> uploadExcelWithFormData(org.apache.poi.ss.usermodel.Workbook workbook,
String fileName, String uploadUrl) {
return Mono.fromCallable(() -> {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
return outputStream.toByteArray();
})
.flatMap(fileBytes -> {
var formData = new org.springframework.util.LinkedMultiValueMap<String, Object>();
formData.add("file", new org.springframework.core.io.ByteArrayResource(fileBytes) {
@Override
public String getFilename() {
return fileName;
}
});
formData.add("filename", fileName);
return webClient.post()
.uri(uploadUrl)
.bodyValue(formData)
.retrieve()
.bodyToMono(String.class);
});
}
/**
* 使用Base64编码的方式上传
*/
public Mono<String> uploadExcelAsBase64(org.apache.poi.ss.usermodel.Workbook workbook,
String fileName, String uploadUrl) {
return Mono.fromCallable(() -> {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] fileBytes = outputStream.toByteArray();
String base64Content = Base64.getEncoder().encodeToString(fileBytes);
return base64Content;
})
.flatMap(base64Content -> {
var requestObject = new UploadRequest();
requestObject.setFileName(fileName);
requestObject.setFileContent(base64Content);
requestObject.setFileType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
return webClient.post()
.uri(uploadUrl)
.bodyValue(requestObject)
.retrieve()
.bodyToMono(String.class);
});
}
// 上传请求对象
static class UploadRequest {
private String fileName;
private String fileContent;
private String fileType;
// Getters and Setters
public String getFileName() { return fileName; }
public void setFileName(String fileName) { this.fileName = fileName; }
public String getFileContent() { return fileContent; }
public void setFileContent(String fileContent) { this.fileContent = fileContent; }
public String getFileType() { return fileType; }
public void setFileType(String fileType) { this.fileType = fileType; }
}
}