Java Poi 在Excel中输出特殊符号

   日期:2020-07-18     浏览:99    评论:0    
核心提示:最近的工作围绕报表导出,并没有集成相应的报表插件,只是使用了Poi。其中有一个需求,Excel中导出特殊符号,如√、×等。在网上找寻了许久,没有相关资料,故记录分享一下。思考良久,走了不少弯路,最后受 System.out.println() 启发,实现方式真的超级简单。每一个特殊符号,都对应一个Unicode编码,我们只需要将特定的符号,转变成Unicode编码,进行输出即可。相应的代码输出:cell.setCellValue(\\u221A);另附自己编写的Excel工具类,支持单表、主

最近的工作围绕报表导出,并没有集成相应的报表插件,只是使用了Poi。其中有一个需求,Excel中导出特殊符号,如√、×等。在网上找寻了许久,没有相关资料,故记录分享一下。

思考良久,走了不少弯路,最后受 System.out.println() 启发,实现方式真的超级简单。每一个特殊符号,都对应一个Unicode编码,我们只需要将特定的符号,转变成Unicode编码,进行输出即可。

相应的代码输出:

cell.setCellValue("\u221A");

另附自己编写的Excel工具类,支持单表、主子表(可定制主表在前还是在后)、图片、特殊符号等。

<dependency>
   <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
package com.king.tools.util;
import java.util.HashMap;
import java.util.Map;



public class ExcelPercentField {
    public final static Map<String,String> percentFiledMap = new HashMap<>();
    static {
   		// 根据实际情况进行设置
        percentFiledMap.put("a","a");
        percentFiledMap.put("b","b");
        percentFiledMap.put("c","c");
    }
}
package com.king.tools.util;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.*;



public class ExcelExport<T> {
    Logger logger = LoggerFactory.getLogger(ExcelExport.class);
    private HSSFWorkbook workbook;
    private HSSFSheet sheet;
    private int rowNum;
    private HSSFPatriarch patriarch ;
    private String fileName;
    private int version;

    public ExcelExport(){}
    public ExcelExport(String fileName, int version) {
        this.fileName = fileName;
        this.version = version;
    }

    
    public void exportExcel(String title, Map<String,List<String>> fields, Collection<T> dataset, String path,boolean childBefore){
        createExcelHSSF(title,fields,null,dataset,DateUtils.YYYY_MM_DD,path,childBefore);
    }

    
    public void exportExcel(String title,Map<String,List<String>> fields,String[] header,Collection<T> dataset,String path,boolean childBefore){
        createExcelHSSF(title,fields,header,dataset,DateUtils.YYYY_MM_DD,path,childBefore);
    }

    
    public void exportExcel(String title,Map<String,List<String>> fields,String[] header,Collection<T> dataset,String pattern,String path,boolean childBefore){
        createExcelHSSF(title,fields,header,dataset,pattern,path,childBefore);
    }

    
    public void exportExcel(String title,Map<String,List<String>> fields, Collection<T> dataset, HttpServletResponse response){
        createExcelHSSF(title,fields,null,dataset,DateUtils.YYYY_MM_DD,response);
    }

    
    public void exportExcel(String title, Map<String,List<String>> fields, String[] header, Collection<T> dataset, HttpServletResponse response){
        createExcelHSSF(title,fields,header,dataset,DateUtils.YYYY_MM_DD,response);
    }

    
    public void exportExcel(String title, Map<String,List<String>> fields, String[] header, Collection<T> dataset, String pattern, HttpServletResponse response){
        createExcelHSSF(title,fields,header,dataset,pattern,response);
    }
    
    private void createExcelHSSF(String title, Map<String,List<String>> fields, String[] header, Collection<T> dataset, String pattern, HttpServletResponse response){
        response.reset(); // 清除buffer缓存
        // 指定下载的文件名
        response.setHeader("Content-Disposition", "attachment;filename=contacts" +(StringUtils.isBlank(fileName)?  DateUtils.dateTimeNow() : fileName) + ".xls");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        createExcel2003(title,fields,header,dataset,pattern, false);
        httpExcelHSSF(workbook,response);
    }

    
    private void createExcelHSSF(String title,Map<String,List<String>> fields,String[] header,Collection<T> dataset,String pattern,String path,boolean childBefore){
        createExcel2003(title,fields,header,dataset,pattern,childBefore);
        ioExcelHSSF(workbook,path);
    }

    
    private void createExcel2003(String title, Map<String, List<String>> fields, String[] header, Collection<T> dataset, String pattern, boolean childBefore){
        // 初始化构建
        initWorkBook();
        // 生成样式
        HSSFCellStyle titleStyle = getTitleStyle(workbook);
        HSSFCellStyle headerStyle = getHeaderStyle(workbook);
        HSSFCellStyle normalStyle = getNormalStyle(workbook);
        HSSFCellStyle footerStyle = getFooterStyle(workbook);
        HSSFCellStyle percentStyle = createPercentStyle(workbook);
        // 创建表头
        createTableTitle(title,header.length-1,titleStyle);
        // 生成标题行
        createTableHead(header,headerStyle);
        // 迭代集合
        Iterator it = dataset.iterator();
        // 获取主表属性字段
        List<String> entityFields = fields.get("entity");
        // 获取子表属性字段
        List<String> childFields = fields.get("children");
        // 主表字段长度
        int entityColumnLength = entityFields.size();
        int childColumnLength = 0;
        if(childFields !=null){
            childColumnLength = childFields.size();
        }
        // 合并行
        int rowspan = 0;
        // 每个对象的子表数据
        Object children = null;
        HSSFRow row;
        HSSFCell cell;
        while (it.hasNext()){
            rowNum ++;
            T t = (T) it.next();
            row = sheet.createRow(rowNum);
            // 确定合并行数
            if(childFields !=null && childFields.size() > 0){
                children = getValue(t,"children");
                if(children !=null && ((ArrayList)children).size()>0){
                    rowspan = ((ArrayList)children).size()-1;
                }
            }
            // 主表字段
            for(int i = 0; i <entityFields.size(); i++){
                Object value = getValue(t,entityFields.get(i));
                // 创建单元格
                if(childBefore){
                    if(ExcelPercentField.percentFiledMap.containsKey(entityFields.get(i))){
                        createTableCell(row.createCell(i+childColumnLength),value,percentStyle,pattern,rowspan);
                    }else{
                        createTableCell(row.createCell(i+childColumnLength),value,normalStyle,pattern,rowspan);
                    }
                }else{
                    if(ExcelPercentField.percentFiledMap.containsKey(entityFields.get(i))){
                        createTableCell(row.createCell(i),value,percentStyle,pattern,rowspan);
                    }else{
                        createTableCell(row.createCell(i),value,normalStyle,pattern,rowspan);
                    }
                }
            }
            // 子表字段
            if(childFields !=null && childFields.size() > 0){
                if(children !=null ){
                    List list = (ArrayList)children;
                    for(int i = 0;i <list.size(); i++){
                        if(i >0){
                            rowNum++;
                            row = sheet.createRow(rowNum);
                        }
                        for(int j = 0;j<childFields.size();j++){
                            Object value = getValue(list.get(i),childFields.get(j));
                            if(childBefore){
                                if(ExcelPercentField.percentFiledMap.containsKey(childFields.get(j))){
                                    createTableCell(row.createCell(j ),value,percentStyle,pattern,rowspan);
                                }else{
                                    createTableCell(row.createCell(j ),value,normalStyle,pattern,rowspan);
                                }
                            }else{
                                if(ExcelPercentField.percentFiledMap.containsKey(childFields.get(j))){
                                    createTableCell(row.createCell(j +entityColumnLength),value,percentStyle,pattern,rowspan);
                                }else{
                                    createTableCell(row.createCell(j +entityColumnLength),value,normalStyle,pattern,rowspan);
                                }

                            }
                        }
                    }
                }
            }
            // 如果需要合并行
            if(rowspan > 0){
               for(int i = 0;i<entityFields.size();i++){
                   CellRangeAddress cellRange = null;
                   if(childBefore){
                       cellRange= new CellRangeAddress(rowNum-rowspan,rowNum,i+childColumnLength,i+childColumnLength);
                   }else{
                       cellRange = new CellRangeAddress(rowNum-rowspan,rowNum,i,i);
                   }
                   sheet.addMergedRegion(cellRange);
                   //添加边框
                   RegionUtil.setBorderTop(BorderStyle.THIN, cellRange, sheet);
                   RegionUtil.setBorderBottom(BorderStyle.THIN, cellRange, sheet);
                   RegionUtil.setBorderLeft(BorderStyle.THIN, cellRange, sheet);
                   RegionUtil.setBorderRight(BorderStyle.THIN, cellRange, sheet);
                   RegionUtil.setTopBorderColor(HSSFColor.HSSFColorPredefined.GREEN.getIndex(),cellRange,sheet);
                   RegionUtil.setBottomBorderColor(HSSFColor.HSSFColorPredefined.GREEN.getIndex(),cellRange,sheet);
                   RegionUtil.setLeftBorderColor(HSSFColor.HSSFColorPredefined.GREEN.getIndex(),cellRange,sheet);
                   RegionUtil.setRightBorderColor(HSSFColor.HSSFColorPredefined.GREEN.getIndex(),cellRange,sheet);
               }
            }
        }
        sheet.autoSizeColumn(2);
        setSizeColumn(sheet,entityColumnLength+childColumnLength);
    }
    
    private void initWorkBook(){
        // 创建一个工作簿
        workbook = HSSFWorkbookFactory.createWorkbook();
        // 创建一个sheet
        sheet = workbook.createSheet();
        // 默认表格列宽
        sheet.setDefaultColumnWidth(18);
        patriarch = sheet.createDrawingPatriarch();
    }
    
    private void createTableTitle(String title,int colspan, HSSFCellStyle headerStyle) {
        if(StringUtils.isBlank(title)){
            return;
        }
        HSSFRow row = sheet.createRow(rowNum);
        row.setHeightInPoints(30f);
        HSSFCell cell = row.createCell(0);
        sheet.addMergedRegion(new CellRangeAddress(rowNum,rowNum,0,colspan));
        cell.setCellStyle(headerStyle);
        cell.setCellValue(title);
        rowNum ++;
    }
    
    private void createTableHead(String[] header, HSSFCellStyle headerStyle) {
        if(header ==null || header.length <1){
            return;
        }
        HSSFRow row = sheet.createRow(rowNum);
        HSSFCell cell;
        for (int i = 0; i < header.length; i++){
            cell = row.createCell(i);
            cell.setCellStyle(headerStyle);
            cell.setCellValue(header[i]);
            cell.setCellType(CellType.STRING);
        }
    }

    
    private void createTableCell(HSSFCell cell, Object value, HSSFCellStyle normalStyle, String pattern, int rowspan) {
        cell.setCellStyle(normalStyle);
        if (value ==null){
            return;
        }
        if(value instanceof Number){
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(value.toString()));
        //日期
        } else if(value instanceof Date){
            cell.setCellType(CellType.STRING);
            cell.setCellValue(DateUtils.parseDateToStr(pattern,(Date)value));
        // 图片
        } else if(value instanceof byte[]){
            cell.getRow().setHeightInPoints(80);
            sheet.setColumnWidth(cell.getColumnIndex(),(short) (34.5 * 110));
            HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0,
                    1023, 255, (short) cell.getColumnIndex(), rowNum, (short) cell.getColumnIndex(), rowNum);
            anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE);
            patriarch.createPicture(anchor, workbook.addPicture(
                    (byte[])value, HSSFWorkbook.PICTURE_TYPE_JPEG));

        }else if(value instanceof Boolean){
            cell.setCellType(CellType.STRING);
            if((boolean)value){
                cell.setCellValue("\u221A");
            }
            // 全部当作字符串处理
        }else{
            cell.setCellType(CellType.STRING);
            cell.setCellValue(new HSSFRichTextString(String.valueOf(value)));
        }
    }

    
    private HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = getNormalStyle(workbook);
        style.getFont(workbook).setFontHeightInPoints((short)12);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    
    private HSSFCellStyle getFooterStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = getNormalStyle(workbook);
        style.getFont(workbook).setFontHeightInPoints((short)12);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.LIME.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return style;
    }

    
    private HSSFCellStyle getHeaderStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = getNormalStyle(workbook);
        style.getFont(workbook).setFontHeightInPoints((short)11);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.LIME.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        HSSFPalette palette = workbook.getCustomPalette();
        palette.setColorAtIndex(IndexedColors.LIME.getIndex(),(byte)198,(byte)224,(byte)180);
        return style;
    }

    
    private HSSFCellStyle createPercentStyle(HSSFWorkbook workbook){
        HSSFCellStyle style = getNormalStyle(workbook);
        style.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00%"));
        return style;
    }

    
    private HSSFCellStyle getNormalStyle(HSSFWorkbook workbook){
        // 创建字体
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short)10);
        // 构建样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置边框
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setTopBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        style.setRightBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        style.setBottomBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        style.setLeftBorderColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex());
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFont(font);
        // 字体默认换行
        style.setWrapText(true);
        return style;
    }


    
    private <E> Object  getValue(E t,String fieldName){
        String methodName = "get"
                + fieldName.substring(0, 1).toUpperCase()
                + fieldName.substring(1);
        try {
            Method method = t.getClass().getMethod(methodName);
            method.setAccessible(true);
            Object value = method.invoke(t);
            return value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    private void ioExcelHSSF(HSSFWorkbook workbook, String path){
        OutputStream ops =null;
        if(StringUtils.isBlank(fileName)){
            path = path + DateUtils.dateTimeNow() +".xls";
        } else {
            path = path + fileName + ".xls";
        }
        try {
            ops = new FileOutputStream(path);
            workbook.write(ops);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(ops != null){
                try {
                    ops.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void httpExcelHSSF(HSSFWorkbook workbook, HttpServletResponse response){
        OutputStream ops = null;
        try {
            ops = response.getOutputStream();
            response.flushBuffer();
            workbook.write(ops);
        } catch (IOException e) {
            e.printStackTrace();
            if(ops !=null){
                try {
                    ops.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    
    private void setSizeColumn(HSSFSheet sheet, int size) {
        for(int i =0;i<size;i++){
            int columnWidth = sheet.getColumnWidth(i) / 256;
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                HSSFRow currentRow;
                //当前行未被使用过
                if (sheet.getRow(rowNum) == null) {
                    currentRow = sheet.createRow(rowNum);
                } else {
                    currentRow = sheet.getRow(rowNum);
                }

                if (currentRow.getCell(i) != null) {
                    HSSFCell currentCell = currentRow.getCell(i);
// if(rowNum==sheet.getLastRowNum()){
// HSSFCellStyle style = currentCell.getCellStyle();
// style.setFillForegroundColor(IndexedColors.LIME.getIndex());
// style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// currentCell.setCellStyle(style);
// }
                    if (currentCell.getCellType() == CellType.STRING) {
                        int length = currentCell.getStringCellValue().getBytes().length;
                        if (columnWidth < length) {
                            columnWidth = length;
                        }
                    }
                }
            }
            sheet.setColumnWidth(i, columnWidth * 256);
        }
    }
}

效果图如下:

但仍遇到一个问题,主子表结构导出,如果图片在主表,合并行之后,图片并不会居中,并且第一行会被撑开,有没有比较简单的方式进行处理(不想重新计算锚点,然后定高输出)?

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服