Skip to main content

New Feature For File Excel and Others

13 November 2023

alurkerja-crud : 1.0.0-20231113.065917-144

Penambahan

setCell (ExcelWriter)

Mengatasi code yang berulang set cell di getRows(...)

Example

Class UserToExcel

@Override
public void getRows(Workbook workbook, Sheet sheet, Row row, User entity) {
setCell(row, 0, new StringValue(entity.getFullname(), ""));
setCell(row, 1, new DateValue(entity.getVerifiedAt(), "", "dd-MM-yyyy"), null);
}

setCell memiliki 2 jenis func, yaitu

  • 3 params, yaitu row, index, class ExcelWritable
    • params pertama untuk atur cell akan di row berapa
    • params kedua untuk atur cell di column berapa
    • params ketiga untuk set value cell
  • 4 params, yaitu row, index, class ExcelWritable, CellStyle
    • params pertama untuk atur cell akan di row berapa
    • params kedua untuk atur cell di column berapa
    • params ketiga untuk set value cell
    • params keempat untuk set style pada cell

new StringValue(entity.getFullname(), "") code bagian ini lah yang jadi perhatian, karena library akan set value ke cell sesuai type class yang di input. Class value yang tersedia saat ini adalah

  • StringValue
  • DoubleValue
  • IntegerValue
  • LongValue
  • DoubleValue
  • DateValue

untuk class value selain DateValue, memiliki 2 params, yaitu value dan defaultValue

  • params pertama untuk set value cell dari entity / real value
  • params kedua untuk set value cell jika params pertama null

untuk class DateValue, memiliki 3 params, yaitu value, defaultValue, dan format

  • params pertama untuk set value cell dari entity / real value
  • params kedua untuk set value cell jika params pertama null
  • params ketiga untuk atur format date, secara default format akan menggunakan yyyy-MM-dd

Class value juga bisa ditambah sendiri jika mendesak (utamakan untuk permintaan penambahan ke AlurKerja), dengan buat class yang di implementasikan dengan class ExcelWritable.

public class StringValue implements ExcelWritable {
private final String value;
private final String defaultValue;

public StringValue(String value, String defaultValue) {
this.value = value;
this.defaultValue = defaultValue == null ? "" : defaultValue;
}

@Override
public void writeCellValue(Cell cell) {
cell.setCellValue(value == null ? defaultValue : value);
}
}

ExcelWriter with parameter sheet names

Menangani export data ke excel yang memerlukan multi sheet. Cara implementasi, cek Example

Example

Class UserToExcel

public class UserToExcel extends ExcelWriter<User> {
public UserToExcel(List<User> categories) {
super(categories);
}

@Override
public List<String> getHeaders() {
ArrayList<String> headers = new ArrayList<>();
headers.add("Name");
headers.add("Tag");
headers.add("Verified At");
return headers;
}

@Override
public void getRows(Workbook workbook, Sheet sheet, Row row, User entity) {
if (sheet.getSheetName().equals("User")) {
setCell(row, 0, new StringValue(entity.getFullname(), ""));
}
else if (sheet.getSheetName().equals("Role")) {
setCell(row, 0, new DateValue(entity.getVerifiedAt(), "", "dd-MM-yyyy"), null);
}
}
}

Pada func getRows(workbook, sheet, row, entity) ini yang akan menangani bagian set value cell. Dengan lakukan pengecekan berdasarkan nama sheet, maka dapat diatur per sheet nya.

Implementasi

@GetMapping("/excel")
public void exportToExcell(HttpServletResponse httpServletResponse) throws IOException {
OutputStream outputStream = httpServletResponse.getOutputStream();

List<User> categories = this.crudService.findAll();
UserToExcel userToExcel = new UserToExcel(categories);
userToExcel.export(outputStream, "User", "Role");
httpServletResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
httpServletResponse.setHeader("Content-Disposition", "attachment;filename=\"user.xlsx\"");

outputStream.flush();
httpServletResponse.flushBuffer();
}

userToExcel.export(outputStream, "User", "Role"); di line code ini yang menjadi perhatian. Disini kita atur apa nama-nama yang akan jadi sheet. Nama sheet yang kita define di line code ini yang akan jadi patokan untuk pengecekan di func getRows(workbook, sheet, row, entity)

ExcelReader with parameter sheet names

Menangani import data dari excel yang mempunyai multi sheet. Cara implementasi, cek Example

Example

Class UserFromExcel

public class UserFromExcel extends ExcelReader<User> {
@Override
public int skippedRow() {
return 0;
}

@Override
public Object perLine(int sheetIndex, Object[] columns) {
if (sheetIndex == 0) {
User user = new User();
user.setFullname((String) columns[0]);
return user;
} else if (sheetIndex == 1) {
Role role = new Role();
role.setVerifiedAt((String) columns[0]);
return role;
}
}
}

Pada func perLine(sheetIndex, columns) ini yang akan menangani bagian set value field. Dengan lakukan pengecekan berdasarkan index sheet, maka dapat diatur per sheet nya.

Implementasi

@PostMapping("/excel")
public ResponseEntity<Object> createFromFile(MultipartFile file) throws IOException {
UserFromExcel userFromExcel = new UserFromExcel();
List<ExcelReadable> categories = userFromExcel.readXlsx(file.getInputStream(), 0, 1);
for(ExcelReadable readable : categories){
if (readable.getSheetIndex() == 0) {
List<User> users = (List<User>) readable.getValues();
// Logic code for sheet index 0
} else if (readable.getSheetIndex() == 1) {
List<Role> roles = (List<Role>) readable.getValues();
// Logic code for sheet index 1
}
}
return success(file.getOriginalFilename() + " was uploaded");
}

List<ExcelReadable> categories = userFromExcel.readXlsx(file.getInputStream(), 0, 1); di line code ini yang menjadi perhatian. Disini kita index yang akan jadi dibaca sheetnya. Index sheet yang kita define di line code ini yang akan jadi patokan untuk pengecekan di func perLine(sheetIndex, columns)

Perubahan

Perbaikan bug func findAll

Bug ini muncul pada versi AlurKerja CRUD sebelumnya, yang disebabkan predicate search yang tetap di set padahal tidak ada field search yang di set value nya

Pemisahan fungsi di ExcelWriter

Sekarang ada fungsi export yang diatur workbook yang dipakai, SXSSFWorkbook / XSSFWorkbook

  • SXSSFWorkbook, disarankan untuk pengolahan data yang banyak (menghemat memori), namun memiliki fitur yang terbatas. Cocok untuk type file .xlsx
  • XSSFWorkbook, disarankan untuk pengolahan data yang tidak banyak, dan memiliki fitur yang banyak. Cocok untuk type file .xls

Pemisahan fungsi di ExcelReader

Sekarang ada fungsi export yang diatur workbook yang dipakai, XSSFWorkbook / HSSFWorkbook

  • XSSFWorkbook, disarankan untuk pengolahan data yang banyak (menghemat memori), Cocok untuk type file .xlsx
  • HSSFWorkbook, disarankan untuk pengolahan data yang tidak banyak. Cocok untuk type file .xls

Deprikasi

read di ExcelReader

Karena menyesuaikan sesuai tujuan (xls dan xlsx) agar mudah memahami mana function yang cocok untuk file xlsx dan xls. Silahkan untuk mengubah ke readXls / readXlsx!

HttpUtil

Karena tidak support untuk mock di UnitTest. Fungsi masih sama, hanya beda class. Silahkan untuk mengubah ke HttpUtilService!