如何修复 class 在 Java 中写入 excel 的错误
How to fix bug with a class that writes to excel in Java
我目前想以异步方式获取用户的详细信息并将这些详细信息转换为 excel 文件。
这是从存储库中创建的数据库中批量获取详细信息的方法。
public CompletableFuture<ArrayList<UserProfile>> fetchUserDetailsBatches(Bson filter){
return CompletableFuture.supplyAsync( () -> {
Bson projection = Projections.fields(Projections.exclude("roleGroup", "roles"));
return this.userCollection.find(filter).projection(projection).skip(1).limit(1000).
into(new ArrayList<>());
});
}
这里是转换成excel文件的class。之前它工作得很好,直到我在更改为 CompleteFuture 之前使用 Stream 时。
public static InputStream writeToExcel(CompletableFuture<ArrayList<UserProfile>> data) throws Exception {
//Blank workbook
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("userDetails report");
AtomicInteger rowNum = new AtomicInteger(1);
AtomicBoolean isHeaderSet = new AtomicBoolean(false);
data.forEach(userProfile -> {
if (!isHeaderSet.get()){
createHeader(userProfile, sheet);
isHeaderSet.set(true);
}
XSSFRow row = sheet.createRow(rowNum.getAndIncrement());
ObjectMapper mapObject = new ObjectMapper();
Map<String, Object> mapObj = mapObject.convertValue(userProfile, Map.class);
AtomicInteger cellNum = new AtomicInteger();
mapObj.forEach((key, value) -> {
XSSFCell cell = row.createCell(cellNum.getAndIncrement());
cell.setCellValue(key);
if (value instanceof Integer)
cell.setCellValue((Integer) value);
else if (value instanceof BigDecimal)
cell.setCellValue(((BigDecimal) value).doubleValue());
else if (value instanceof Long)
cell.setCellValue((Long) value);
else cell.setCellValue(String.valueOf(value));
});
});
try {
//Write the workbook in file system
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
InputStream is = new ByteArrayInputStream(barray);
log.info("userDetails.csv written successfully on disk.");
return is;
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
@Cremer 已修复此错误。此处返回 ID 的文件,我希望将其保存在 S3 存储桶中,并且 url link 将发送到用户的电子邮件。
这就是我正在做但没有工作的。
public BaseResponse<Object> uploadDownloads(HttpServletRequest request, InputStream fileInputStream,
FormDataContentDisposition fileDetail, String documentType){
String url = " ";
try {
int contentLength = request.getContentLength();
if (contentLength == -1 || contentLength > FILE_SIZE_MAX) {
throw new Exception("File size must be less than 5mb");
}
String fileName = fileDetail.getFileName();
int index = fileName.lastIndexOf('.');
String extension = index > 0 ? fileName.substring(index) : "";
final String unique_name = fileName + "_" + documentType + extension;
final String filePath = String.format("file/%s", unique_name);
url = awsFactory.putS3Object(filePath, fileInputStream, "csv/" + fileDetail.getFileName().substring(index + 1));
return BaseResponse.<Object>builder()
.status(true)
.responseCode("00")
.message(SUCCESS)
.data(url)
.build();
} catch (Exception ase) {
ase.printStackTrace();
return BaseResponse.<Object>builder()
.status(false)
.responseCode("96")
.message(ase.getMessage())
.data(null)
.build();
}
}
这是 s3 存储桶的样子
public String putS3Object(String objectKey, InputStream inputStream, String contentType) throws IOException {
try {
awsCreds = AwsBasicCredentials.create(getAccessKey(), getSecretKey());
Region region = Region.EU_WEST_2;
S3Client s3 = S3Client.builder()
.region(region)
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.build();
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.contentDisposition(String.format("inline; filename:%s", objectKey))
.contentType(contentType)
.build();
s3.putObject(objectRequest, RequestBody.fromBytes(inputStream.readAllBytes()));
return String.valueOf(s3.utilities().getUrl(
GetUrlRequest.builder().bucket(bucketName).key(objectKey).region(region).build()));
} catch (SdkServiceException e) {
e.printStackTrace();
log.info(e.getMessage());
}
return null;
}
这是控制器的样子
@GET
@Path("/uploadReport/")
@Timed
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response uploadDownloads( @Context final HttpServletRequest request,
@NotNull final String id,@FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") final FormDataContentDisposition fileDetail,
@FormDataParam("documentType") String documentType) {
//
// log.info("this is the userId -> {}", id);
return Response.status(Response.Status.OK).entity(
userProfileService.uploadDownloads(request, fileInputStream, fileDetail, documentType)
).build();
}
您需要等待加载 Future(这里是您的参数数据),然后执行此操作 或者您可以调用 data.get() 然后开始使用 '.foreach ',它会停止当前线程,只要它需要完成未来。
编辑:
只需将下面的方法替换为:
public static InputStream writeToExcel(CompletableFuture<ArrayList<UserProfile>> data) throws Exception {
//Blank workbook
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("userDetails report");
AtomicInteger rowNum = new AtomicInteger(1);
AtomicBoolean isHeaderSet = new AtomicBoolean(false);
data.get().forEach(userProfile -> {
if (!isHeaderSet.get()){
createHeader(userProfile, sheet);
isHeaderSet.set(true);
}
XSSFRow row = sheet.createRow(rowNum.getAndIncrement());
ObjectMapper mapObject = new ObjectMapper();
Map<String, Object> mapObj = mapObject.convertValue(userProfile, Map.class);
AtomicInteger cellNum = new AtomicInteger();
mapObj.forEach((key, value) -> {
XSSFCell cell = row.createCell(cellNum.getAndIncrement());
cell.setCellValue(key);
if (value instanceof Integer)
cell.setCellValue((Integer) value);
else if (value instanceof BigDecimal)
cell.setCellValue(((BigDecimal) value).doubleValue());
else if (value instanceof Long)
cell.setCellValue((Long) value);
else cell.setCellValue(String.valueOf(value));
});
});
try {
//Write the workbook in file system
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
InputStream is = new ByteArrayInputStream(barray);
log.info("userDetails.csv written successfully on disk.");
return is;
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
我目前想以异步方式获取用户的详细信息并将这些详细信息转换为 excel 文件。
这是从存储库中创建的数据库中批量获取详细信息的方法。
public CompletableFuture<ArrayList<UserProfile>> fetchUserDetailsBatches(Bson filter){
return CompletableFuture.supplyAsync( () -> {
Bson projection = Projections.fields(Projections.exclude("roleGroup", "roles"));
return this.userCollection.find(filter).projection(projection).skip(1).limit(1000).
into(new ArrayList<>());
});
}
这里是转换成excel文件的class。之前它工作得很好,直到我在更改为 CompleteFuture 之前使用 Stream 时。
public static InputStream writeToExcel(CompletableFuture<ArrayList<UserProfile>> data) throws Exception {
//Blank workbook
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("userDetails report");
AtomicInteger rowNum = new AtomicInteger(1);
AtomicBoolean isHeaderSet = new AtomicBoolean(false);
data.forEach(userProfile -> {
if (!isHeaderSet.get()){
createHeader(userProfile, sheet);
isHeaderSet.set(true);
}
XSSFRow row = sheet.createRow(rowNum.getAndIncrement());
ObjectMapper mapObject = new ObjectMapper();
Map<String, Object> mapObj = mapObject.convertValue(userProfile, Map.class);
AtomicInteger cellNum = new AtomicInteger();
mapObj.forEach((key, value) -> {
XSSFCell cell = row.createCell(cellNum.getAndIncrement());
cell.setCellValue(key);
if (value instanceof Integer)
cell.setCellValue((Integer) value);
else if (value instanceof BigDecimal)
cell.setCellValue(((BigDecimal) value).doubleValue());
else if (value instanceof Long)
cell.setCellValue((Long) value);
else cell.setCellValue(String.valueOf(value));
});
});
try {
//Write the workbook in file system
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
InputStream is = new ByteArrayInputStream(barray);
log.info("userDetails.csv written successfully on disk.");
return is;
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
@Cremer 已修复此错误。此处返回 ID 的文件,我希望将其保存在 S3 存储桶中,并且 url link 将发送到用户的电子邮件。
这就是我正在做但没有工作的。
public BaseResponse<Object> uploadDownloads(HttpServletRequest request, InputStream fileInputStream,
FormDataContentDisposition fileDetail, String documentType){
String url = " ";
try {
int contentLength = request.getContentLength();
if (contentLength == -1 || contentLength > FILE_SIZE_MAX) {
throw new Exception("File size must be less than 5mb");
}
String fileName = fileDetail.getFileName();
int index = fileName.lastIndexOf('.');
String extension = index > 0 ? fileName.substring(index) : "";
final String unique_name = fileName + "_" + documentType + extension;
final String filePath = String.format("file/%s", unique_name);
url = awsFactory.putS3Object(filePath, fileInputStream, "csv/" + fileDetail.getFileName().substring(index + 1));
return BaseResponse.<Object>builder()
.status(true)
.responseCode("00")
.message(SUCCESS)
.data(url)
.build();
} catch (Exception ase) {
ase.printStackTrace();
return BaseResponse.<Object>builder()
.status(false)
.responseCode("96")
.message(ase.getMessage())
.data(null)
.build();
}
}
这是 s3 存储桶的样子
public String putS3Object(String objectKey, InputStream inputStream, String contentType) throws IOException {
try {
awsCreds = AwsBasicCredentials.create(getAccessKey(), getSecretKey());
Region region = Region.EU_WEST_2;
S3Client s3 = S3Client.builder()
.region(region)
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.build();
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.contentDisposition(String.format("inline; filename:%s", objectKey))
.contentType(contentType)
.build();
s3.putObject(objectRequest, RequestBody.fromBytes(inputStream.readAllBytes()));
return String.valueOf(s3.utilities().getUrl(
GetUrlRequest.builder().bucket(bucketName).key(objectKey).region(region).build()));
} catch (SdkServiceException e) {
e.printStackTrace();
log.info(e.getMessage());
}
return null;
}
这是控制器的样子
@GET
@Path("/uploadReport/")
@Timed
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response uploadDownloads( @Context final HttpServletRequest request,
@NotNull final String id,@FormDataParam("file") final InputStream fileInputStream,
@FormDataParam("file") final FormDataContentDisposition fileDetail,
@FormDataParam("documentType") String documentType) {
//
// log.info("this is the userId -> {}", id);
return Response.status(Response.Status.OK).entity(
userProfileService.uploadDownloads(request, fileInputStream, fileDetail, documentType)
).build();
}
您需要等待加载 Future(这里是您的参数数据),然后执行此操作
编辑: 只需将下面的方法替换为:
public static InputStream writeToExcel(CompletableFuture<ArrayList<UserProfile>> data) throws Exception {
//Blank workbook
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("userDetails report");
AtomicInteger rowNum = new AtomicInteger(1);
AtomicBoolean isHeaderSet = new AtomicBoolean(false);
data.get().forEach(userProfile -> {
if (!isHeaderSet.get()){
createHeader(userProfile, sheet);
isHeaderSet.set(true);
}
XSSFRow row = sheet.createRow(rowNum.getAndIncrement());
ObjectMapper mapObject = new ObjectMapper();
Map<String, Object> mapObj = mapObject.convertValue(userProfile, Map.class);
AtomicInteger cellNum = new AtomicInteger();
mapObj.forEach((key, value) -> {
XSSFCell cell = row.createCell(cellNum.getAndIncrement());
cell.setCellValue(key);
if (value instanceof Integer)
cell.setCellValue((Integer) value);
else if (value instanceof BigDecimal)
cell.setCellValue(((BigDecimal) value).doubleValue());
else if (value instanceof Long)
cell.setCellValue((Long) value);
else cell.setCellValue(String.valueOf(value));
});
});
try {
//Write the workbook in file system
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
byte[] barray = bos.toByteArray();
InputStream is = new ByteArrayInputStream(barray);
log.info("userDetails.csv written successfully on disk.");
return is;
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}