### Read Specific Columns to Map List Synchronously Source: https://fesod.apache.org/docs/sheet/read/simple Uses .includeColumnIndexes to filter columns, which are then mapped to sequential integer keys starting from 0. ```java @Test public void readSpecificColumnsToMapList() { String fileName = "path/to/demo.xlsx"; // We only want to read Column A (Index 0) and Column C (Index 2) List targetColumns = Arrays.asList(0, 2); List> list = FesodSheet.read(fileName) .sheet() .includeColumnIndexes(targetColumns) .doReadSync(); for (Map data : list) { // Column Index 0 is mapped to key 0 String id = data.get(0); // Column Index 2 is mapped sequentially to key 1 String age = data.get(1); log.info("ID: {}, Age: {}", id, age); } } ``` -------------------------------- ### Import GPG Keys Source: https://fesod.apache.org/docs/download Import the project release KEYS file into your local GPG keyring to enable signature verification. ```bash gpg --import KEYS ``` -------------------------------- ### Get Total Rows in Listener Source: https://fesod.apache.org/docs/sheet/help/faq Retrieves the approximate total row count within an AnalysisEventListener. ```java @Override public void doAfterAllAnalysed(AnalysisContext context) { int totalRows = context.readSheetHolder().getApproximateTotalRowNumber(); System.out.println("Total rows: " + totalRows); } ``` -------------------------------- ### Insert Comments with RowWriteHandler Source: https://fesod.apache.org/docs/sheet/help/core-class Implement RowWriteHandler to add cell comments. This example targets the header row specifically. ```java @Slf4j public class CommentRowWriteHandler implements RowWriteHandler { @Override public void afterRowDispose(RowWriteHandlerContext context) { if (BooleanUtils.isTrue(context.getHead())) { Sheet sheet = context.getWriteSheetHolder().getSheet(); Drawing drawing = sheet.createDrawingPatriarch(); // Create a comment Comment comment = drawing.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 1, 0, (short) 2, 1)); comment.setString(new XSSFRichTextString("This is a comment")); sheet.getRow(0).getCell(1).setCellComment(comment); log.info("Comment inserted at first row, second column"); } } } ``` ```java @Test public void commentWrite() { String fileName = "commentWrite.xlsx"; FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(new CommentRowWriteHandler()) .sheet("Insert Comment") .doWrite(data()); } ``` -------------------------------- ### Perform Simple Fill with POJO or Map Source: https://fesod.apache.org/docs/sheet/fill Demonstrates filling a template using either a POJO object or a Map structure. ```java @Test public void simpleFill() { String templateFileName = "path/to/simple.xlsx"; // Approach 1: Fill based on object FillData fillData = new FillData(); fillData.setName("张三"); fillData.setNumber(5.2); FesodSheet.write("simpleFill.xlsx") .withTemplate(templateFileName) .sheet() .doFill(fillData); // Approach 2: Fill based on Map Map map = new HashMap<>(); map.put("name", "张三"); map.put("number", 5.2); FesodSheet.write("simpleFillMap.xlsx") .withTemplate(templateFileName) .sheet() .doFill(map); } ``` -------------------------------- ### Perform List Fill and Batch Filling Source: https://fesod.apache.org/docs/sheet/fill Shows how to fill multiple data items at once or perform batch filling using an ExcelWriter. ```java @Test public void listFill() { String templateFileName = "path/to/list.xlsx"; // Approach 1: Fill all data at once FesodSheet.write("listFill.xlsx") .withTemplate(templateFileName) .sheet() .doFill(data()); // Approach 2: Batch filling try (ExcelWriter writer = FesodSheet.write("listFillBatch.xlsx").withTemplate(templateFileName).build()) { WriteSheet writeSheet = FesodSheet.writerSheet().build(); writer.fill(data(), writeSheet); writer.fill(data(), writeSheet); } } ``` -------------------------------- ### Execute Merge Writing Source: https://fesod.apache.org/docs/sheet/write/extra Demonstrates both annotation-based and custom strategy-based merging during the write process. ```java @Test public void mergeWrite() { String fileName = "mergeWrite" + System.currentTimeMillis() + ".xlsx"; // Annotation approach FesodSheet.write(fileName, DemoMergeData.class) .sheet("合并示例") .doWrite(data()); // Custom merge strategy FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(new CustomMergeStrategy()) .sheet("自定义合并") .doWrite(data()); } ``` -------------------------------- ### Verify SHA-512 Checksum Source: https://fesod.apache.org/docs/download Verify the integrity of the downloaded file using the SHA-512 checksum. ```bash shasum -a 512 -c apache-fesod-X.X.X-incubating-src.tar.gz.sha512 ``` ```bash sha512sum -c apache-fesod-X.X.X-incubating-src.tar.gz.sha512 ``` -------------------------------- ### Perform Template-based Writing Source: https://fesod.apache.org/docs/sheet/write/extra Use the withTemplate method to fill data into a pre-existing Excel template file. ```java @Test public void templateWrite() { String templateFileName = "path/to/template.xlsx"; String fileName = "templateWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, DemoData.class) .withTemplate(templateFileName) .sheet() .doWrite(data()); } ``` -------------------------------- ### Configure Gradle Dependency Source: https://fesod.apache.org/docs/quickstart/guide Add this implementation line to your build.gradle file to include Apache Fesod in your Gradle project. ```groovy dependencies { implementation 'org.apache.fesod:fesod-sheet:2.0.2-incubating' } ``` -------------------------------- ### Verify GPG Signature Source: https://fesod.apache.org/docs/download Verify the authenticity of the downloaded source release using the corresponding .asc signature file. ```bash gpg --verify apache-fesod-X.X.X-incubating-src.tar.gz.asc apache-fesod-X.X.X-incubating-src.tar.gz ``` -------------------------------- ### Write Data Without POJO Source: https://fesod.apache.org/docs/sheet/write/pojo Use List> for headers and List> for data to write to Excel without requiring a dedicated entity class. ```java @Test public void noModelWrite() { String fileName = "noModelWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName) .head(head()) // Dynamic headers .sheet("无对象写入") .doWrite(dataList()); } private List> head() { return Arrays.asList( Collections.singletonList("字符串标题"), Collections.singletonList("数字标题"), Collections.singletonList("日期标题")); } private List> dataList() { List> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { list.add(Arrays.asList("字符串" + i, 0.56, new Date())); } return list; } ``` -------------------------------- ### Configure Maven Dependencies Source: https://fesod.apache.org/docs/sheet/read/spring Include these dependencies in your pom.xml to enable Fesod and Spring Boot web functionality. ```xml org.apache.fesod fesod {version.number} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter ``` -------------------------------- ### Enable debug logging for performance monitoring Source: https://fesod.apache.org/docs/sheet/help/faq Configure the logger level to DEBUG for the org.apache.fesod package to monitor performance. ```java LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); ch.qos.logback.classic.Logger logger = lc.getLogger("org.apache.fesod"); logger.setLevel(Level.DEBUG); ``` -------------------------------- ### Create Spring Controller for Uploads Source: https://fesod.apache.org/docs/sheet/read/spring Define a REST endpoint to receive MultipartFile uploads and trigger the Fesod reading process. ```java @RestController @RequestMapping("/excel") public class ExcelController { @PostMapping("/upload") public ResponseEntity upload(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("Please select a file to upload!"); } try { FesodSheet.read(file.getInputStream(), UploadData.class, new UploadDataListener()) .sheet() .doRead(); return ResponseEntity.ok("File uploaded and processed successfully!"); } catch (IOException e) { log.error("File processing failed", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File processing failed"); } } } ``` -------------------------------- ### Fill Complex Data in Excel Templates Source: https://fesod.apache.org/docs/sheet/fill Demonstrates filling a template with both list data and individual variables. Uses FillConfig to force new rows when processing lists. ```java @Test public void complexFill() { String templateFileName = "path/to/complex.xlsx"; try (ExcelWriter writer = FesodSheet.write("complexFill.xlsx").withTemplate(templateFileName).build()) { WriteSheet writeSheet = FesodSheet.writerSheet().build(); // Fill list data, with forceNewRow enabled FillConfig config = FillConfig.builder().forceNewRow(true).build(); writer.fill(data(), config, writeSheet); // Fill regular variables Map map = new HashMap<>(); map.put("date", "2024年11月20日"); map.put("total", 1000); writer.fill(map, writeSheet); } } ``` -------------------------------- ### Write Large Files with Batching and Compression Source: https://fesod.apache.org/docs/sheet/advanced/large-file Uses a try-with-resources block to manage the ExcelWriter and enables SXSSFWorkbook temp file compression via a WorkbookWriteHandler. ```java @Test public void largeFileWrite() { String fileName = "largeFile" + System.currentTimeMillis() + ".xlsx"; try (ExcelWriter excelWriter = FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(new WorkbookWriteHandler() { @Override public void afterWorkbookCreate(WorkbookWriteHandlerContext context) { Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); if (workbook instanceof SXSSFWorkbook) { ((SXSSFWorkbook) workbook).setCompressTempFiles(true); } } }) .build()) { WriteSheet writeSheet = FesodSheet.writerSheet("Template").build(); // Write data in batches — each data() call returns one batch for (int i = 0; i < 1000; i++) { excelWriter.write(data(), writeSheet); } } } ``` -------------------------------- ### Batch Import Data with AnalysisEventListener Source: https://fesod.apache.org/docs/sheet/help/core-class Implements batch processing by caching rows and saving them once a threshold is reached. ```java @Slf4j public class DemoDataListener extends AnalysisEventListener { private static final int BATCH_COUNT = 100; // The amount of data processed in each batch private List cachedDataList = new ArrayList<>(BATCH_COUNT); @Override public void invoke(DemoData data, AnalysisContext context) { log.info("Parse to a single piece of data: {}", JSON.toJSONString(data)); cachedDataList.add(data); // If the amount of cached data reaches BATCH_COUNT, perform batch processing. if (cachedDataList.size() >= BATCH_COUNT) { saveData(); cachedDataList.clear(); // Clear the cache } } @Override public void doAfterAllAnalysed(AnalysisContext context) { // Process the remaining data if (!cachedDataList.isEmpty()) { saveData(); } log.info("All data analysis completed!"); } private void saveData() { log.info("Store {} pieces of data to the database", cachedDataList.size()); // Implement data processing logic } @Override public void onException(Exception exception, AnalysisContext context) { log.error("An error occurred during the analysis process.: {}", exception.getMessage()); // Can record abnormal data or re-throw exceptions. } } ``` ```java @Test public void simpleRead() { String fileName = "path/to/demo.xlsx"; FesodSheet.read(fileName, DemoData.class, new DemoDataListener()) .sheet() // Read the first sheet by default .doRead(); } ``` -------------------------------- ### Write Dynamic Headers Source: https://fesod.apache.org/docs/sheet/write/head Generate headers programmatically by passing a List of Lists to the head() method. ```java @Test public void dynamicHeadWrite() { String fileName = "dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx"; List> head = Arrays.asList( Collections.singletonList("动态字符串标题"), Collections.singletonList("动态数字标题"), Collections.singletonList("动态日期标题")); FesodSheet.write(fileName) .head(head) .sheet() .doWrite(data()); } ``` -------------------------------- ### Generate Data List Source: https://fesod.apache.org/docs/sheet/write/simple Create a list of DemoData objects to be written to the spreadsheet. ```java private List data() { List list = ListUtils.newArrayList(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); data.setString("String" + i); data.setDate(new Date()); data.setDoubleData(0.56); list.add(data); } return list; } ``` -------------------------------- ### Package Import Replacements Source: https://fesod.apache.org/docs/migration/from-fastexcel Replace legacy cn.idev.excel imports with the corresponding org.apache.fesod.sheet packages. ```java import cn.idev.excel.exception.ExcelAnalysisException; -> import org.apache.fesod.sheet.exception.ExcelAnalysisException; ``` ```java import cn.idev.excel.exception.ExcelAnalysisStopException; -> import org.apache.fesod.sheet.exception.ExcelAnalysisStopException; ``` ```java import cn.idev.excel.exception.ExcelCommonException; -> import org.apache.fesod.sheet.exception.ExcelCommonException; ``` ```java import cn.idev.excel.exception.ExcelGenerateException; -> import org.apache.fesod.sheet.exception.ExcelGenerateException; ``` ```java import cn.idev.excel.metadata.data.WriteCellData; -> import org.apache.fesod.sheet.metadata.data.WriteCellData; ``` ```java import cn.idev.excel.metadata.data.ReadCellData; -> import org.apache.fesod.sheet.metadata.data.ReadCellData; ``` ```java import cn.idev.excel.metadata.CellExtra; -> import org.apache.fesod.sheet.metadata.CellExtra; ``` ```java import cn.idev.excel.metadata.Head; -> import org.apache.fesod.sheet.metadata.Head; ``` ```java import cn.idev.excel.metadata.property.ExcelContentProperty; -> import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; ``` -------------------------------- ### Define POJO for Spreadsheet Data Source: https://fesod.apache.org/docs/sheet/read/spring Create a POJO class to map the spreadsheet columns to Java fields. ```java @Getter @Setter @ToString public class UploadData { private String string; private Date date; private Double doubleData; } ``` -------------------------------- ### Configure CSV using CSVFormat Source: https://fesod.apache.org/docs/sheet/read/csv Directly applies an Apache Commons CSVFormat object to the reader configuration. ```java @Test public void csvFormatDemo() { CSVFormat csvFormat = CSVFormat.DEFAULT.builder().setDelimiter(CsvConstant.AT).build(); String csvFile = "path/to/your.csv"; try (ExcelReader excelReader = FesodSheet.read(csvFile, DemoData.class, new DemoDataListener()).build()) { ReadWorkbookHolder readWorkbookHolder = excelReader.analysisContext().readWorkbookHolder(); // Check if it's an instance of CsvReadWorkbookHolder if (readWorkbookHolder instanceof CsvReadWorkbookHolder) { CsvReadWorkbookHolder csvReadWorkbookHolder = (CsvReadWorkbookHolder) readWorkbookHolder; csvReadWorkbookHolder.setCsvFormat(csvFormat); } ReadSheet readSheet = FesodSheet.readSheet(0).build(); excelReader.read(readSheet); } } ``` -------------------------------- ### ReadListener Interface Methods Source: https://fesod.apache.org/docs/sheet/help/core-class Core methods available for implementation when using the ReadListener interface to process spreadsheet data. ```APIDOC ## ReadListener ### Description A generic interface for processing spreadsheet data row-by-row. Implement this interface to define custom logic for data parsing, header processing, and exception handling. ### Methods - **invoke(T data, AnalysisContext context)**: Triggered when a line of data is read. `data` is the parsed current line object. - **doAfterAllAnalysed(AnalysisContext context)**: Called after all data parsing is complete; used for resource release or final processing. - **onException(Exception exception, AnalysisContext context)**: (Optional) Captures exceptions during the reading process. - **invokeHead(Map> headMap, AnalysisContext context)**: (Optional) Provides access to header information for dynamic processing. ``` -------------------------------- ### Implement a ReadListener for POJO data Source: https://fesod.apache.org/docs/sheet/read/simple Create a custom listener by implementing ReadListener to process each record and handle completion events. ```java @Slf4j public class DemoDataListener implements ReadListener { @Override public void invoke(DemoData data, AnalysisContext context) { log.info("Read one record: {}", JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("All data reading completed!"); } } ``` -------------------------------- ### Implement Listener for Map-based Reading Source: https://fesod.apache.org/docs/sheet/read/pojo Create a listener to process data as a Map when no POJO class is defined. ```java @Slf4j public class NoModelDataListener extends AnalysisEventListener> { @Override public void invoke(Map data, AnalysisContext context) { log.info("Read one record: {}", JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("All data reading completed!"); } } ``` -------------------------------- ### Fill Large Data Sets in Excel Templates Source: https://fesod.apache.org/docs/sheet/fill Optimizes performance for large data by filling lists and appending statistical information using WriteTable. ```java @Test public void complexFillWithTable() { String templateFileName = "path/to/complexFillWithTable.xlsx"; try (ExcelWriter writer = FesodSheet.write("complexFillWithTable.xlsx").withTemplate(templateFileName).build()) { WriteSheet writeSheet = FesodSheet.writerSheet().build(); // Fill list data writer.fill(data(), writeSheet); // Fill list data Map map = new HashMap<>(); map.put("date", "2024年11月20日"); writer.fill(map, writeSheet); // Fill statistical information List> totalList = new ArrayList<>(); totalList.add(Arrays.asList(null, null, null, "统计: 1000")); writer.write(totalList, writeSheet); } } ``` -------------------------------- ### Implement Hyperlink Extra Listener Source: https://fesod.apache.org/docs/sheet/read/extra A ReadListener implementation to capture and log Excel cell hyperlinks. ```java @Slf4j public class DemoHyperLinkExtraListener implements ReadListener { @Override public void invoke(DemoData data, AnalysisContext context) {} @Override public void doAfterAllAnalysed(AnalysisContext context) {} @Override public void extra(CellExtra extra, AnalysisContext context) { log.info("Read extra information: {}", JSON.toJSONString(extra)); if(CellExtraTypeEnum.HYPERLINK == extra.getType()) { log.info("Hyperlink information: {}", extra.getText()); } } } ``` -------------------------------- ### Execute Custom Merge Strategy Write Source: https://fesod.apache.org/docs/sheet/write/merge Register the custom strategy class during the write process. ```java @Test public void customMergeWrite() { String fileName = "customMergeWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(new CustomMergeStrategy()) .sheet() .doWrite(data()); } ``` -------------------------------- ### Configure Maven Dependency Source: https://fesod.apache.org/docs/quickstart/guide Add this dependency to your pom.xml file to include Apache Fesod in your Maven project. ```xml org.apache.fesod fesod-sheet 2.0.2-incubating ``` -------------------------------- ### Implement Custom Converter Source: https://fesod.apache.org/docs/sheet/read/converter Create a class implementing the Converter interface to define custom logic for converting between Java types and Excel cell data. ```java public class CustomStringStringConverter implements Converter { @Override public Class supportJavaTypeKey() { return String.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public String convertToJavaData(ReadConverterContext context) { return "Custom: " + context.getReadCellData().getStringValue(); } @Override public WriteCellData convertToExcelData(WriteConverterContext context) { return new WriteCellData<>(context.getValue()); } } ``` -------------------------------- ### Define Styles with Annotations Source: https://fesod.apache.org/docs/sheet/write/style Use annotations like @HeadStyle, @HeadFontStyle, @ContentStyle, and @ContentFontStyle on class or field levels to customize Excel output formatting. ```java @Getter @Setter @EqualsAndHashCode // Set header background to red @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 10) // Set header font size to 20 @HeadFontStyle(fontHeightInPoints = 20) // Set content background to green @ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 17) // Set content font size to 20 @ContentFontStyle(fontHeightInPoints = 20) public class DemoStyleData { // Individually set header and content styles for a specific column @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 14) @HeadFontStyle(fontHeightInPoints = 30) @ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40) @ContentFontStyle(fontHeightInPoints = 30) @ExcelProperty("字符串标题") private String string; @ExcelProperty("日期标题") private Date date; @ExcelProperty("数字标题") private Double doubleData; } ``` -------------------------------- ### Write Spreadsheet using Data List Source: https://fesod.apache.org/docs/sheet/write/simple Pass a list of data directly to the doWrite method. ```java @Test public void simpleWrite() { String fileName = "simpleWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, DemoData.class) .sheet("Sheet1") .doWrite(data()); } ``` -------------------------------- ### Read Excel File with Formatting Source: https://fesod.apache.org/docs/sheet/read/format Execute the read operation using the configured POJO class to apply formatting rules during data ingestion. ```java @Test public void converterRead() { String fileName = "path/to/demo.xlsx"; FesodSheet.read(fileName, ConverterData.class, new PageReadListener(dataList -> { for (ConverterData data : dataList) { log.info("Read a row of data: {}", JSON.toJSONString(data)); } })).sheet().doRead(); } ``` -------------------------------- ### Configure CSVFormat Directly Source: https://fesod.apache.org/docs/sheet/write/csv Manually builds and applies a CSVFormat object to the CsvWorkbook. ```java @Test public void csvFormatDemo() { CSVFormat csvFormat = CSVFormat.DEFAULT.builder().setDelimiter(CsvConstant.AT).build(); String csvFile = "path/to/your.csv"; try (ExcelWriter excelWriter = FesodSheet.write(csvFile, DemoData.class).excelType(ExcelTypeEnum.CSV).build()) { WriteWorkbookHolder writeWorkbookHolder = excelWriter.writeContext().writeWorkbookHolder(); Workbook workbook = writeWorkbookHolder.getWorkbook(); // Check if it's an instance of CsvWorkbook if (workbook instanceof CsvWorkbook) { CsvWorkbook csvWorkbook = (CsvWorkbook) workbook; csvWorkbook.setCsvFormat(csvFormat); writeWorkbookHolder.setWorkbook(csvWorkbook); } WriteSheet writeSheet = FesodSheet.writerSheet(0).build(); excelWriter.write(data(), writeSheet); } } ``` -------------------------------- ### Define Column Order with POJO Source: https://fesod.apache.org/docs/sheet/write/pojo Use the @ExcelProperty annotation with the index attribute to explicitly define the column sequence in the output file. ```java @Getter @Setter @EqualsAndHashCode public class IndexData { @ExcelProperty(value = "字符串标题", index = 0) private String string; @ExcelProperty(value = "日期标题", index = 1) private Date date; @ExcelProperty(value = "数字标题", index = 3) private Double doubleData; } ``` ```java @Test public void indexWrite() { String fileName = "indexWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, IndexData.class) .sheet() .doWrite(data()); } ``` -------------------------------- ### Generate Spreadsheet Download in Spring Controller Source: https://fesod.apache.org/docs/sheet/write/spring Use this method in a Spring Boot controller to stream a generated spreadsheet directly to the HTTP response. ```java @GetMapping("download") public void download(HttpServletResponse response) throws IOException { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); String fileName = URLEncoder.encode("demo", "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); FesodSheet.write(response.getOutputStream(), DemoData.class) .sheet("Sheet1") .doWrite(data()); } ``` -------------------------------- ### Write Images to Excel Source: https://fesod.apache.org/docs/sheet/write/image Demonstrates writing a list of image data objects to an Excel file using FesodSheet. ```java @Test public void imageWrite() throws Exception { String fileName = "imageWrite" + System.currentTimeMillis() + ".xlsx"; String imagePath = "path/to/image.jpg"; List list = new ArrayList<>(); ImageDemoData data = new ImageDemoData(); data.setFile(new File(imagePath)); data.setByteArray(Files.readAllBytes(Paths.get(imagePath))); data.setUrl(new URL("https://example.com/image.jpg")); list.add(data); FesodSheet.write(fileName, ImageDemoData.class) .sheet() .doWrite(list); } ``` -------------------------------- ### Apply styles with HorizontalCellStyleStrategy Source: https://fesod.apache.org/docs/sheet/write/style Use this strategy to define separate styles for headers and content cells during the write process. ```java @Test public void handlerStyleWrite() { String fileName = "handlerStyleWrite" + System.currentTimeMillis() + ".xlsx"; // Define header style WriteCellStyle headStyle = new WriteCellStyle(); headStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); // Red background WriteFont headFont = new WriteFont(); headFont.setFontHeightInPoints((short) 20); // Font size 20 headStyle.setWriteFont(headFont); // Define content style WriteCellStyle contentStyle = new WriteCellStyle(); contentStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // Green background contentStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); WriteFont contentFont = new WriteFont(); contentFont.setFontHeightInPoints((short) 20); contentStyle.setWriteFont(contentFont); // Use strategy to set styles HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(headStyle, contentStyle); FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(styleStrategy) .sheet("样式模板") .doWrite(data()); } ``` -------------------------------- ### Customize Cell Styles with AbstractCellStyleStrategy Source: https://fesod.apache.org/docs/sheet/help/faq Extend this class to define custom cell styles for headers and content. Ensure the order is specified to control execution sequence. ```java public class CustomCellStyleWriteHandler extends AbstractCellStyleStrategy { @Override public int order() { // Customize the execution order return OrderConstant.SHEET_ORDER; } @Override protected void setHeadCellStyle(CellWriteHandlerContext context) { // Customize the head cell style } @Override protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { CellStyle style = cell.getSheet().getWorkbook().createCellStyle(); style.setFillForegroundColor(IndexedColors.RED.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); cell.setCellStyle(style); } } ``` -------------------------------- ### Update Gradle Dependencies Source: https://fesod.apache.org/docs/migration/from-fastexcel Update the implementation dependency in your build.gradle file to point to the Apache Fesod artifact. ```groovy implementation 'cn.idev.excel:fastexcel:1.3.0' ``` ```groovy implementation 'org.apache.fesod:fesod-sheet:2.0.2-incubating' ``` -------------------------------- ### Define Row and Column Dimensions via Annotations Source: https://fesod.apache.org/docs/sheet/write/style Uses class-level and field-level annotations to set default and specific row heights and column widths. ```java @Getter @Setter @EqualsAndHashCode @ContentRowHeight(20) @HeadRowHeight(30) @ColumnWidth(25) // Default column width public class WidthAndHeightData { @ExcelProperty("字符串标题") private String string; @ExcelProperty("日期标题") private Date date; @ColumnWidth(50) // Individually set column width @ExcelProperty("数字标题") private Double doubleData; } ``` ```java @Test public void widthAndHeightWrite() { String fileName = "widthAndHeightWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, WidthAndHeightData.class) .sheet() .doWrite(data()); } ``` -------------------------------- ### Execute Styled Write Operation Source: https://fesod.apache.org/docs/sheet/write/style Perform the write operation using the configured entity class to apply the defined styles to the generated Excel file. ```java @Test public void annotationStyleWrite() { String fileName = "annotationStyleWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, DemoStyleData.class) .sheet() .doWrite(data()); } ``` -------------------------------- ### WriteBasicParameter Source: https://fesod.apache.org/docs/sheet/help/parameter Configuration parameters for controlling the writing process, including header handling, styling, and column filtering. ```APIDOC ## WriteBasicParameter ### Description Defines parameters for customizing the spreadsheet writing process, such as header merging strategies and column exclusion/inclusion. ### Parameters - **customWriteHandlerList** (List) - Optional - Writing handlers (Workbook, Sheet, Row, or Cell level). - **relativeHeadRowIndex** (Integer) - Optional - Number of rows to leave blank above the spreadsheet (Default: 0). - **needHead** (Boolean) - Optional - Whether to write the header (Default: true). - **useDefaultStyle** (Boolean) - Optional - Whether to use default styles (Default: true). - **automaticMergeHead** (Boolean) - Optional - Automatically merge headers (Default: true). - **headerMergeStrategy** (Enum) - Optional - Strategy for merging headers: NONE, HORIZONTAL_ONLY, VERTICAL_ONLY, FULL_RECTANGLE, AUTO. - **excludeColumnIndexes** (List) - Optional - Indexes of data to exclude. - **excludeColumnFieldNames** (List) - Optional - Field names of data to exclude. - **includeColumnIndexes** (List) - Optional - Indexes of data to include. - **includeColumnFieldNames** (List) - Optional - Field names of data to include. - **orderByIncludeColumn** (Boolean) - Optional - Sort according to the order of the collection passed in (Default: false). ### Example FesodSheet.write(fileName).head(head).headerMergeStrategy(HeaderMergeStrategy.FULL_RECTANGLE).sheet().doWrite(data()); ``` -------------------------------- ### Implement custom CellWriteHandler Source: https://fesod.apache.org/docs/sheet/write/style Create a custom handler by implementing the CellWriteHandler interface to gain full control over cell styling. ```java @Slf4j public class CustomCellStyleWriteHandler implements CellWriteHandler { @Override public void afterCellDispose(CellWriteHandlerContext context) { // Only set styles for content cells if (BooleanUtils.isNotTrue(context.getHead())) { WriteCellData cellData = context.getFirstCellData(); WriteCellStyle writeCellStyle = cellData.getOrCreateStyle(); // Set background color to yellow writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex()); writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND); // Set font to blue WriteFont writeFont = new WriteFont(); writeFont.setColor(IndexedColors.BLUE.getIndex()); writeFont.setFontHeightInPoints((short) 14); // Font size 14 writeCellStyle.setWriteFont(writeFont); log.info("已自定义单元格样式: 行 {}, 列 {}", context.getRowIndex(), context.getColumnIndex()); } } } ``` -------------------------------- ### Execute Formatted Write Operation Source: https://fesod.apache.org/docs/sheet/write/format Perform the write operation using the FesodSheet utility with the annotated POJO class. ```java @Test public void converterWrite() { String fileName = "converterWrite" + System.currentTimeMillis() + ".xlsx"; FesodSheet.write(fileName, ConverterData.class) .sheet() .doWrite(data()); } ``` -------------------------------- ### Force Memory Storage for Spreadsheet Reading Source: https://fesod.apache.org/docs/sheet/help/large-data Use MapCache to force memory storage for faster processing when memory is sufficient. ```java // Force memory storage, so a 20M spreadsheet file will use 150M of memory (many temporary objects, so 100M will be constantly GC'd). // This will be much more efficient than the complex strategy above. // Just to clarify, all I did was add the readCache(new MapCache()) parameter. For the rest, refer to other examples. FesodSheet.read(). readCache(new MapCache()); ``` -------------------------------- ### Wildcard Import Replacements Source: https://fesod.apache.org/docs/migration/from-fastexcel Update wildcard imports to point to the new Fesod sheet package. ```java import cn.idev.excel. -> import org.apache.fesod.sheet. ``` ```java import org.apache.fesod.excel. -> import org.apache.fesod.sheet. ``` -------------------------------- ### Configure Header Merge Strategy Source: https://fesod.apache.org/docs/sheet/help/parameter Sets the header merge strategy to FULL_RECTANGLE during the write process. ```java FesodSheet.write(fileName) .head(head) .headerMergeStrategy(HeaderMergeStrategy.FULL_RECTANGLE) .sheet() .doWrite(data()); ``` -------------------------------- ### Entry Class Import Replacements Source: https://fesod.apache.org/docs/migration/from-fastexcel Update imports for the deprecated FastExcel entry classes to FesodSheet. ```java import org.apache.fesod.sheet.FastExcel; -> import org.apache.fesod.sheet.FesodSheet; ``` ```java import org.apache.fesod.sheet.FastExcelFactory; -> import org.apache.fesod.sheet.FesodSheet; ``` -------------------------------- ### Read Spreadsheet with POJO Source: https://fesod.apache.org/docs/sheet/read/pojo Execute the read operation using the defined POJO class and a listener. ```java @Test public void indexOrNameRead() { String fileName = "path/to/demo.xlsx"; FesodSheet.read(fileName, IndexOrNameData.class, new DemoDataListener()) .sheet() .doRead(); } ``` -------------------------------- ### Define POJO with Format Annotations Source: https://fesod.apache.org/docs/sheet/read/converter Use @ExcelProperty with a custom converter, @DateTimeFormat, or @NumberFormat to specify data conversion rules on class fields. ```java @Getter @Setter @EqualsAndHashCode public class ConverterData { @ExcelProperty(converter = CustomStringStringConverter.class) private String string; @DateTimeFormat("yyyyMMddHHmmss") private String date; @NumberFormat("#.##%") private String doubleData; } ``` -------------------------------- ### Write Using Tables Source: https://fesod.apache.org/docs/sheet/write/sheet Segments data within a single sheet by defining multiple tables. ```java @Test public void tableWrite() { String fileName = "tableWrite" + System.currentTimeMillis() + ".xlsx"; try (ExcelWriter excelWriter = FesodSheet.write(fileName, DemoData.class).build()) { WriteSheet writeSheet = FesodSheet.writerSheet("Table示例").build(); WriteTable table1 = FesodSheet.writerTable(0).build(); WriteTable table2 = FesodSheet.writerTable(1).build(); excelWriter.write(data(), writeSheet, table1); excelWriter.write(data(), writeSheet, table2); } } ``` -------------------------------- ### Configure Memory Allocation for Large Files Source: https://fesod.apache.org/docs/sheet/help/large-data Use SimpleReadCacheSelector to define memory thresholds for shared strings and cache data when handling high concurrency or extremely large files. ```java // The first parameter specifies how many MB of shared string data will be stored in the file (default is 5 MB). // The second parameter specifies how many MB of cache data will be stored in memory when using file storage (default is 20 MB). // For example, if you want to use 100 MB of memory (this refers to permanent memory usage during parsing, excluding temporary objects) to parse a spreadsheet file, the calculation shows it to be approximately 20 MB + 90 MB, so set the parameters to: 20 and 90. // Here's a clarification: the only addition is the readCacheSelector(new SimpleReadCacheSelector(5, 20)) parameter; the rest follows the examples provided. FesodSheet.read(). readCacheSelector(new SimpleReadCacheSelector(5, 20)); ``` -------------------------------- ### Update Maven Dependencies Source: https://fesod.apache.org/docs/migration/from-fastexcel Replace the cn.idev FastExcel dependency with the Apache Fesod equivalent in your pom.xml file. ```xml cn.idev.excel fastexcel 1.3.0 ``` ```xml org.apache.fesod fesod-sheet 2.0.2-incubating ``` -------------------------------- ### FastExcelFactory Call Site Replacements Source: https://fesod.apache.org/docs/migration/from-fastexcel Replace static method calls from FastExcelFactory with FesodSheet equivalents. ```java FastExcelFactory.read() -> FesodSheet.read() ``` ```java FastExcelFactory.write() -> FesodSheet.write() ``` ```java FastExcelFactory.writerSheet() -> FesodSheet.writerSheet() ``` ```java FastExcelFactory.readSheet() -> FesodSheet.readSheet() ``` ```java FastExcelFactory.writerTable() -> FesodSheet.writerTable() ``` -------------------------------- ### Define POJO with Column Mapping Source: https://fesod.apache.org/docs/sheet/read/pojo Use @ExcelProperty to map fields by index or column name. ```java @Getter @Setter @EqualsAndHashCode public class IndexOrNameData { @ExcelProperty(index = 2) private Double doubleData; @ExcelProperty("String Title") private String string; @ExcelProperty("Date Title") private Date date; } ``` -------------------------------- ### Implement a listener for map-based data reading Source: https://fesod.apache.org/docs/sheet/read/simple Use AnalysisEventListener with Map to read data without a predefined POJO class. ```java @Slf4j public class NoModelDataListener extends AnalysisEventListener> { @Override public void invoke(Map data, AnalysisContext context) { log.info("Read one record: {}", JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("All data reading completed!"); } } ``` -------------------------------- ### WriteWorkbook Source: https://fesod.apache.org/docs/sheet/help/parameter Configuration parameters for the workbook output, including file types, streams, and memory management. ```APIDOC ## WriteWorkbook ### Description Configures the workbook output settings, including file format, stream handling, and memory processing options. ### Parameters - **excelType** (String) - Optional - Spreadsheet type (XLS, XLSX, CSV). - **outputStream** (Stream) - Optional - Output stream for the file. - **file** (File) - Optional - Target file for writing. - **templateInputStream** (Stream) - Optional - Template file stream. - **templateFile** (File) - Optional - Template file. - **charset** (Charset) - Optional - Encoding for CSV files. - **autoCloseStream** (Boolean) - Optional - Automatically close the write stream (Default: true). - **password** (String) - Optional - Password for the file. - **inMemory** (Boolean) - Optional - Process in memory (Default: false). - **writeExcelOnException** (Boolean) - Optional - Write data even if an exception occurs (Default: false). - **withBom** (Boolean) - Optional - Set encoding prefix for CSV (Default: true). - **mandatoryUseInputStream** (Boolean) - Optional - Force use of inputStream (Default: false). - **csvFormat** (Object) - Optional - CSVFormat object for CSV files. ``` -------------------------------- ### Implement ReadListener for Table Header Analysis Source: https://fesod.apache.org/docs/sheet/help/core-class Override invokeHead to capture and process table header information during the read process. ```java @Slf4j public class HeadDataListener implements ReadListener { @Override public void invokeHead(Map> headMap, AnalysisContext context) { log.info("Analyse to table header: {}", JSON.toJSONString(headMap)); } @Override public void invoke(DemoData data, AnalysisContext context) { log.info("Analyse the data: {}", JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("All data analysis completed!"); } } ``` ```java @Test public void readWithHead() { String fileName = "path/to/demo.xlsx"; FesodSheet.read(fileName, DemoData.class, new HeadDataListener()) .sheet() // Read the first sheet by default .doRead(); } ``` -------------------------------- ### Process Table Headers with AnalysisEventListener Source: https://fesod.apache.org/docs/sheet/help/core-class Uses invokeHead to capture and process Excel header information. ```java @Slf4j public class DemoDataListenerWithHead extends AnalysisEventListener { @Override public void invokeHead(Map> headMap, AnalysisContext context) { log.info("Parse header data: {}", JSON.toJSONString(headMap)); } @Override public void invoke(DemoData data, AnalysisContext context) { log.info("Analyse the data: {}", JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("All data analysis completed!"); } @Override public void onException(Exception exception, AnalysisContext context) { log.error("An error occurred during reading: {}", exception.getMessage()); } } ``` ```java @Test public void readWithHead() { String fileName = "path/to/demo.xlsx"; FesodSheet.read(fileName, DemoData.class, new DemoDataListenerWithHead()) .sheet() // Read the first sheet by default .doRead(); } ``` -------------------------------- ### Execute Strategy-Based Merge Write Source: https://fesod.apache.org/docs/sheet/write/merge Register a LoopMergeStrategy at runtime to apply merging to specific columns without modifying the POJO. ```java @Test public void strategyMergeWrite() { String fileName = "strategyMergeWrite" + System.currentTimeMillis() + ".xlsx"; // Merge every 2 rows in column 0 LoopMergeStrategy strategy = new LoopMergeStrategy(2, 0); FesodSheet.write(fileName, DemoData.class) .registerWriteHandler(strategy) .sheet() .doWrite(data()); } ``` -------------------------------- ### FastExcel Call Site Replacements Source: https://fesod.apache.org/docs/migration/from-fastexcel Replace static method calls from FastExcel with FesodSheet equivalents. ```java FastExcel.read() -> FesodSheet.read() ``` ```java FastExcel.write() -> FesodSheet.write() ``` ```java FastExcel.writerSheet() -> FesodSheet.writerSheet() ``` ```java FastExcel.readSheet() -> FesodSheet.readSheet() ``` ```java FastExcel.writerTable() -> FesodSheet.writerTable() ```