如何修复 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());

    }
}