0

So, I am trying to build a report. The details of some certain type of users need to be written in an excel file. On hitting the endpoint it returns 500 with the following stacktrace.

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class java.lang.String (java.util.LinkedHashMap and java.lang.String are in module java.base of loader 'bootstrap')
        at com.clever.bas.util.Helpers.lambda$writeToExcel$0(Helpers.java:73)
        at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
        at com.clever.bas.util.Helpers.lambda$writeToExcel$1(Helpers.java:64)
     

Here is the helper class that is throwing the error

public static InputStream writeToExcel(Stream<UserProfile> data) throws Exception {

//        final Map<String, Transaction> transaction = data.collect(Collectors.toMap(Transaction::getId, Function.identity()));

//        System.out.println(transaction + " +++++>>>>>>");


        //Blank workbook
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {

            //Create a blank sheet
            XSSFSheet sheet = workbook.createSheet("transaction 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) value);

                });
            });

I have checked the internet and none of what I have seem so far seems to be solving my problems. There is a List in the models as seen below

public class UserProfile {


    @Id
    @ObjectId
    private String id;

    @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssZ")
    private final Date createdAt = new Date(System.currentTimeMillis());

    @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssZ")
    private final Date updatedAt = new Date(System.currentTimeMillis());


    private String agentId;

    @NotBlank
    private String firstName;

    @NotBlank
    private String lastName;

    @NotBlank
    @Email(message="Invalid email Address")
    private String email;

    @NotBlank
    @Size(min=11, max=14)
    private String phoneNumber;

    private String businessName;

    @Size(min=11, max=11)
    private String bvn;

    @Size(min=11, max=11)
    private String nin;

    @URL
    private String profilePicture;

    @URL
    private String utilityBill;

    @URL
    private String identityCard;

    private RoleGroup roleGroup;

    @Embedded
    private List<Role> roles;

    @ObjectId
    @JsonIgnore
    private List<String> roleIds;

    private String userType; // STAFF, AGENT, AGGREGATOR, PROSPECT

    public Types.Gender gender;

    private String referralCode;

    private String referral;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    private Date dateOfBirth;

    private Types.VerificationStatus verificationStatus;

    private Types.ApprovalStatus approvalStatus;

    private boolean enabled;

    private boolean verified = false;

    private String address;
    private String city;
    private String lga;
    private String state;
    private String terminalId;
    private String accountNumber;
    private Double msc;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String transactionPin;

    @Transient
    private boolean hasPin;


    public ClPrincipal toPrincipal() {
        ClPrincipal principal = new ClPrincipal();
        principal.setProfileId(this.id);
        principal.setUsername(this.email);
        principal.setFirstname(this.firstName);
        principal.setLastname(this.lastName);
        principal.setRoleGroup(this.roleGroup.getName());
        principal.setRoles(new ArrayList<>());
        return principal;
    }

    public UserByTerminalDTO toUserTerminalDto(){
        UserByTerminalDTO user = new UserByTerminalDTO();
        user.setUserID(this.id);
        user.setFirstName(this.firstName);
        user.setLastName(this.lastName);
        user.setMsc(this.msc);
        return user;
    }

    public String fullName(){
        return this.firstName + " " + this.lastName;
    }

    public boolean isHasPin() {
        return Objects.nonNull(this.transactionPin) && !this.transactionPin.trim().isEmpty();
    }

}

It is some of the details of this model UserProfile that I want to write into an excel sheet and make it available for download. How do you think i solve the problem. The major error is coming from these lines particularly the one in bold

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) value);**
    
                    });
                });
4
  • What is line 73 of Helpers? Commented Nov 25, 2021 at 9:11
  • @dan1st else cell.setCellValue((String) value); Commented Nov 25, 2021 at 9:23
  • I think you want cell.setCellValue(String.valueOf(value)); or put it inside an else if (value instanceof String) as casting only works if value is a String. Commented Nov 25, 2021 at 9:24
  • @dan1st thanks. It solved my problem. Commented Nov 25, 2021 at 9:39

1 Answer 1

1

You're making an assumption that for the else branch, the value can only be a String, but from the error it looks like it is in fact a LinkedHashMap.

Make sure that whatever data you work with, you also treat the case where the value is a Map and write that accordingly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.