excel-plus Java Library

repository·dev·Indexed 41 days ago

https://github.com/hellokaton/excel-plus

A high-performance Java library for reading and generating Excel files (XLS, XLSX, and CSV) using an annotation-driven approach. It features a fluent API via Reader and Writer classes, support for custom cell styling, template-based exporting, and integration with Apache POI 4.0.1. Developers can map Java model fields to columns using the @ExcelColumn annotation and implement custom data transformations via the Converter interface.

Tokens
5.8K
Snippets
25
Records
26
Agent score
51%

What's inside excel-plus

  1. How excel-plus works: Annotation-driven mapping

    dev

    excel-plus uses annotations to map Java class fields to Excel columns. This allows you to define how data is read from or written to an Excel file directly within your domain models.

    Key annotations:

    • @ExcelColumn: Used to define the mapping.
      • title: The header name in the Excel file.
      • index: The zero-based column index.
      • datePattern: A custom date format string (e.g., "yyyy-MM-dd") for date/time fields.
    @ExcelColumn(title = "发卡日期", index = 14, datePattern = "M/d/yyyy HH:mm")
    private Date sendCardTime;
  2. Core objects in excel-plus

    dev

    The following classes form the core API of the library:

    • ExcelPlus: The primary entry point for reading and exporting Excel documents.
    • Converter: The interface used to implement custom data type transformations.
    • ReaderResult: A container for the results of an Excel read operation, which includes the list of objects and any validation error messages.
    • Exporter: A configuration object used to define export settings such as styles, templates, and column configurations.
  3. Map Excel columns using @ExcelColumn

    dev

    To read or write data using a Java model, use the @ExcelColumn annotation to map class fields to specific Excel columns. You can specify the column index and date patterns for date fields.

    Key attributes:

    • index: The zero-based column index.
    • datePattern: The pattern used for date formatting.
    public class Sample {
    
        @ExcelColumn(index = 0, datePattern = "M/d/yy")
        private LocalDate date;
    
        @ExcelColumn(index = 1)
        private String location;
    
        @ExcelColumn(index = 4)
        private int proportion;
    
        @ExcelColumn(index = 5)
        private double ss;
    
        @ExcelColumn(index = 6)
        private BigDecimal amount;
        
        // getter setter omitted
    }
  4. Install excel-plus via Maven

    dev

    Add the excel-plus dependency to your pom.xml. Note that this library uses Apache POI version 4.0.1. If your project already has a POI dependency, you should exclude or remove it to avoid conflicts.

    To use the latest stable version:

    <dependency>
        <groupId>io.github.biezhi</groupId>
        <artifactId>excel-plus</artifactId>
        <version>1.0.8</version>
    </dependency>

    To use the snapshot version (for the latest bug fixes and features), you must also add the Sonatype snapshots repository to your pom.xml:

    <repositories>
        <repository>
            <id>snapshots-repo</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    
    <dependency>
        <groupId>io.github.biezhi</groupId>
        <artifactId>excel-plus</artifactId>
        <version>1.0.8-SNAPSHOT</version>
    </dependency>
  5. Filter data during Excel reading

    dev

    You can filter the rows being read by converting the reader output to a Stream using .asStream(). This allows you to use standard Java Stream API filtering before collecting the results.

    List<Sample> samples = Reader.create(Sample.class)
                    .from(new File(classPath() + "/SampleData.xlsx"))
                    .sheet("SalesOrders")
                    .startRow(1)
                    .asStream()
                    .filter(sample -> sample.getAmount().intValue() > 1000)
                    .collect(toList());
  6. Export a list of objects to an Excel file

    dev

    Use ExcelPlus.export() with a list of annotated model objects, then call writeAsFile() to save the result.

    ExcelPlus excelPlus = new ExcelPlus();
    List<CardSecret> cardSecrets = new ArrayList<>();
    // ... add data to list
    
    excelPlus.export(cardSecrets).writeAsFile(new File("卡密列表.xlsx"));
  7. Read data from an Excel file into a List

    dev

    Use Reader.create() to specify the file, and excelPlus.read() to map the rows to your model class. Use .asList() to retrieve the final list.

    Reader reader = Reader.create().excelFile(new File("卡密列表.xlsx"));
    List<CardSecret> cardList = excelPlus.read(CardSecret.class, reader).asList();
  8. Download Excel via Servlet Response

    dev

    To trigger a file download directly in a web browser using a Servlet-based application, use ResponseWrapper.createXLSX (or other formats) within the .to() method of the Writer.

    Writer.create()
          ... 
          .to(ResponseWrapper.createXLSX(servletResponse, "xxx表格.xlsx"))
  9. Apply custom styles to Excel headers

    dev

    To customize styles (font, color, alignment), use Exporter.create() and provide a headerStyle lambda that accepts an Apache POI Workbook. This allows you to manipulate the CellStyle directly.

    List<CardSecret> cardSecrets = this.buildCardSecrets();
    
    Exporter<CardSecret> exporter = Exporter.create(cardSecrets);
    exporter.headerStyle(workbook -> {
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setAlignment(HorizontalAlignment.LEFT);
        headerStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    
        Font headerFont = workbook.createFont();
        headerFont.setFontHeightInPoints((short) 12);
        headerFont.setBold(true);
        headerStyle.setFont(headerFont);
        return headerStyle;
    });
    
    excelPlus.export(exporter).writeAsFile(new File("卡密列表.xlsx"));
  10. Define Excel data models using @ExcelField

    dev

    Use the @ExcelField annotation on your Java model classes to map fields to Excel columns. This allows you to control column order, names, date patterns, and data type conversion.

    Key attributes:

    • order: The column index (starting from 0).
    • columnName: The header name in the Excel file (required).
    • datePattern: The format pattern for Date, LocalDate, or LocalDateTime fields.
    • convertType: A class implementing the Converter interface for custom data transformation.
    public class CardSecret {
    
        @ExcelField(order = 0, columnName = "运营商类型", 
                    convertType = CardTypeConverter.class)
        private Integer cardType;
    
        @ExcelField(order = 1, columnName = "卡密")
        private String secret;
    
        @ExcelField(order = 2, columnName = "面额")
        private BigDecimal amount;
    
        @ExcelField(order = 3, columnName = "过期时间", datePattern = "yyyy年MM月dd日")
        private Date expiredDate;
        
        @ExcelField(order = 5, columnName = "使用情况", convertType = UsedTypeConverter.class)
        private Boolean used;
    
        // getters and setters...
    }
  11. Validate rows during Excel reading

    dev

    Use the .valid() method to perform row-level validation. If a row fails validation, it is excluded from the successful list, and error messages are captured in a ReaderResult object.

    ReaderResult<CardSecret> result = excelPlus.read(new File("卡密列表.xls"), CardSecret.class)
             .valid((index, cardSecret) -> {
                if(!cardSecret.getUsed()){
                    return ValidRow.ok();
                }
                return ValidRow.fail("已经被使用");
             });
    
    if (!result.isValid()) {
        result.errors().forEach(System.out::println);
    } else {
        System.out.println(result.asList().size());
    }