1. 程式人生 > >通用Excel下載

通用Excel下載

用於excel生成,下載。
1.自定義Excel註解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *  用於Excel生成,註明列的名稱和其他屬性
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface
ExcelColumnName { /** * 列的表頭名稱 * @return */ String name() default "-"; /** * 用於日期格式化的字串,預設 yyyy-MM-dd HH:mm:ss * @return */ String dateFormat() default "yyyy-MM-dd hh:mm:ss"; }

2.Excel通用類

import com.pingan.haofang.leshan.common.utils.DateUtils;
import
org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CreationHelper; import org.springframework.
http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.net.URLEncoder; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Excel file generator */ public class ExcelGenerator { private HSSFWorkbook workbook; public ExcelGenerator() { this.workbook = new HSSFWorkbook(); } private List<Field> getFieldsWithAnnotations(Class rowClass) { // get all fields with annotation "ExcelColumnName" List<Field> rowFields = Arrays.stream(rowClass.getDeclaredFields()) .filter(f -> f.isAnnotationPresent(ExcelColumnName.class)) .collect(Collectors.toList()); return rowFields; } private List<String> getColumnNames(Class rowClass) { List<Field> rowFields = getFieldsWithAnnotations(rowClass); List<String> rowNames = rowFields.stream() .map(f -> getColumnName(f)).collect(Collectors.toList()); return rowNames; } private String getColumnName(Field columnField) { return columnField.getAnnotation(ExcelColumnName.class).name(); } private String getDateFormat(Field columnField) { return columnField.getAnnotation(ExcelColumnName.class).dateFormat(); } /** * 通過物件列表構造Excel Sheet * @param sheetName 插入的sheet名稱 * @param rowClass rowObjs的型別 * @param rowObjs 構成表格的物件列表 * @throws IllegalAccessException */ public void addSheetFromArray(String sheetName, Class rowClass, Object[] rowObjs) throws IllegalAccessException { addSheetFromArray(sheetName, rowClass, rowObjs, Collections.emptyList(), Collections.emptyMap()); } /** * 通過物件列表構造Excel Sheet * @param sheetName 插入的sheet名稱 * @param rowClass rowObjs的型別 * @param rowObjs 構成表格的物件列表 * @param columnsToShow 要顯示的列(如不需要請留空) * @param columnMapping 需要重新命名的列mapping * @throws IllegalAccessException */ public void addSheetFromArray(String sheetName, Class rowClass, Object[] rowObjs, List<String> columnsToShow, Map<String, String> columnMapping) throws IllegalAccessException { List<Field> rowFields; // create new sheet on workbook HSSFSheet sheet = this.workbook.createSheet(sheetName); // create header HSSFRow head = sheet.createRow(0); // filter columns to show if (columnsToShow != null && !columnsToShow.isEmpty()) { List<Field> allFields = getFieldsWithAnnotations(rowClass); Map<String, Field> fieldMap = new HashMap<String, Field>(); allFields.forEach(f -> { String columnName = getColumnName(f); fieldMap.put(columnName, f); }); rowFields = columnsToShow.stream().map(c -> fieldMap.get(c)).collect(Collectors.toList()); } else { // get all fields with annotation "ExcelColumnName" rowFields = getFieldsWithAnnotations(rowClass); } // getColumnNames List<String> columnNames = rowFields.stream().map(f -> getColumnName(f)).collect(Collectors.toList()); columnNames = columnNames.stream().map(name -> columnMapping.getOrDefault(name, name)) .collect(Collectors.toList()); // add column names to header for (int i = 0; i < columnNames.size(); i++) { head.createCell(i).setCellValue(columnNames.get(i)); } // set all fields accessible rowFields.forEach(f -> f.setAccessible(true)); // write data to sheet for (int i = 0; i < rowObjs.length; i++) { // create new row HSSFRow dataRow = sheet.createRow(i+1); // get object for current row Object rowObj = rowObjs[i]; for (int j = 0; j < rowFields.size(); j++) { // get current field value Field field = rowFields.get(j); Object cellValue = field.get(rowObj); // set cell value with correct type if(cellValue == null) {continue;} if (field.getType() == boolean.class) { dataRow.createCell(j).setCellValue((boolean)cellValue); } else if (field.getType() == Calendar.class || field.getType() == Date.class) { // generate Date format HSSFCell cell = dataRow.createCell(j); CellStyle cellStyle = workbook.createCellStyle(); CreationHelper helper = workbook.getCreationHelper(); String dateFormat = getDateFormat(field); cellStyle.setDataFormat(helper.createDataFormat().getFormat(dateFormat)); if (field.getType() == Calendar.class) { cell.setCellValue((Calendar) cellValue); } else { cell.setCellValue((Date) cellValue); } cell.setCellStyle(cellStyle); } else if (field.getType() == String.class) { dataRow.createCell(j).setCellValue(cellValue.toString()); } else { String cellValueString = cellValue.toString(); try { // if cell value can be convert to double double cellValueDouble = Double.parseDouble(cellValueString); dataRow.createCell(j).setCellValue(cellValueDouble); } catch (NumberFormatException e) { // if not, convert to string by default dataRow.createCell(j).setCellValue(cellValueString); } } } } } public byte[] generateExcelFileContent() throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); workbook.write(outputStream); return outputStream.toByteArray(); } public static String generateExcelFileNameWithDate(String name) { String date = DateUtils.formatDate(new Date(), "yyyy-MM-dd"); return name + date + ".xls"; } public static String generateExcelFileNameWithDateUTF8(String name) { try { return URLEncoder.encode(generateExcelFileNameWithDate(name), "UTF-8"); } catch (UnsupportedEncodingException e) { return ""; } } public ResponseEntity generateResponseEntity(String name) { try { byte[] body = this.generateExcelFileContent(); String fileName = generateExcelFileNameWithDateUTF8(name); return ResponseEntity.ok() .contentLength(body.length) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName) .contentType(MediaType.parseMediaType("application/vnd.ms-excel")) .body(body); } catch (Exception e) { return ResponseEntity.badRequest().build(); } } }

3.程式碼示例

import com.pingan.haofang.common.excelutil.ExcelColumnName;
import com.pingan.haofang.common.excelutil.ExcelGenerator;
import com.pingan.haofang.leshan.common.constants.WebConstants;
import io.swagger.annotations.Api;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Date;

/**
 * Excel生成示例
 */
@RestController
@RequestMapping(WebConstants.WEB_PREFIX + "/example")
@Api(tags = "ExcelExample", description = "Excel生成示例")
public class ExcelExampleController {
    @RequestMapping(value = "/download", method = RequestMethod.GET)
    public ResponseEntity GenerateExcelFile() {
        // 示例資料Array
        ExampleClass[] exampleData = {
                new ExampleClass("張三", "111222333", (float)-99.999, new Date("03/15/2018")),
                new ExampleClass("隔壁老王", "444555666", (float)100.1, new Date("03/15/2018"))};

        ExcelGenerator excelGenerator = new ExcelGenerator();
        try {
            excelGenerator.addSheetFromArray("Contacts", ExampleClass.class, exampleData);
            byte[] body = excelGenerator.generateExcelFileContent();
			String nowTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
            return ResponseEntity.ok()
                    .contentLength(body.length)
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ URLEncoder.encode("測試示例", "UTF-8")+nowTime+".xls")
                    .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                    .body(body);

        } catch (IllegalAccessException e) {

        } catch (IOException e) {

        }
        return  ResponseEntity.notFound().build();

    }

    // 需要轉換為Excel的資料類
    class ExampleClass{

        // 新增annotation註明該列表頭的名稱
        @ExcelColumnName(name = "姓名")
        private String name;
        @ExcelColumnName(name = "電話號碼")
        private String phoneNumber;
        @ExcelColumnName(name = "薪水")
        private float salary;
        @ExcelColumnName(name = "過期", dateFormat = "yyyy-MM-dd")
        private Date expriy;

        public ExampleClass(String name, String phoneNumber, float salary, Date expiry) {
            this.name = name;
            this.phoneNumber = phoneNumber;
            this.salary = salary;
            this.expriy = expiry;
        }
    }
}