Reputation: 82
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);**
});
});
Upvotes: 0
Views: 3371
Reputation: 447
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.
Upvotes: 1