Java导出自定义样式的Excel表格(poi)

excel.png

1添加依赖(或导入jar包)

 <dependencies>
  <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
  <dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.14</version>
  </dependency>
</dependencies>

2编辑Excel表格

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class Excel {

    private HSSFWorkbook workbook;
    private HSSFSheet sheet;
    private String bDate;
    private int year;

    /**
     * 创建行元素
     * @param style    样式
     * @param height   行高
     * @param value    行显示的内容
     * @param row1     起始行
     * @param row2     结束行
     * @param col1     起始列
     * @param col2     结束列
     */
    private void createRow(HSSFCellStyle style, int height, String value, int row1, int row2, int col1, int col2){

        sheet.addMergedRegion(new CellRangeAddress(row1, row2, col1, col2));  //设置从第row1行合并到第row2行,第col1列合并到col2列
        HSSFRow rows = sheet.createRow(row1);        //设置第几行
        rows.setHeight((short) height);              //设置行高
        HSSFCell cell = rows.createCell(col1);       //设置内容开始的列
        cell.setCellStyle(style);                    //设置样式
        cell.setCellValue(value);                    //设置该行的值
    } 

    /**
     * 创建样式
     * @param fontSize   字体大小
     * @param align  水平位置  左右居中2 居右3 默认居左 垂直均为居中
     * @param bold   是否加粗
     * @return
     */
    private HSSFCellStyle getStyle(int fontSize,int align,boolean bold,boolean border){
        HSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) fontSize);// 字体大小
        if (bold){
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        }
        HSSFCellStyle style = workbook.createCellStyle();
        style.setFont(font);                         //设置字体
        style.setAlignment((short) align);          // 左右居中2 居右3 默认居左
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中1
        if (border){
            style.setBorderRight((short) 2);
            style.setBorderLeft((short) 2);
            style.setBorderBottom((short) 2);
            style.setBorderTop((short) 2);
            style.setLocked(true);
        }
        return style;
    }

    /**
     * 根据数据集生成Excel,并返回Excel文件流
     * @param data 数据集
     * @param sheetName Excel中sheet单元名称
     * @param headNames 列表头名称数组
     * @param colKeys 列key,数据集根据该key进行按顺序取值
     * @return
     * @throws IOException
     */
    public InputStream getExcelFile(List<Map> data, String sheetName, String[] headNames,
                                    String[] colKeys, int colWidths[],String bDate) throws IOException {
        this.bDate = bDate;
        workbook = new HSSFWorkbook();
        sheet = workbook.createSheet(sheetName);
        // 创建表头 startRow代表表体开始的行
        int startRow = createHeadCell( headNames, colWidths);

        // 创建表体数据
        HSSFCellStyle cellStyle = getStyle(14,2,false,true); // 建立新的cell样式
        setCellData(data, cellStyle, startRow, colKeys);

        //创建表尾
        createTailCell(data.size()+4,headNames.length);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        byte[] ba = baos.toByteArray();
        ByteArrayInputStream bais = new ByteArrayInputStream(ba);
        return bais;
    }

    /**
     * 创建表头
     *
     * @param headNames
     * @param colWidths
     */
    private int createHeadCell( String[] headNames, int colWidths[]) {
        // 表头标题
        HSSFCellStyle titleStyle = getStyle(22,2,true,false);//样式
        createRow(titleStyle,0x549,"XX科技收入对账单",0,0,0,headNames.length-1);
        //第二行
        HSSFCellStyle unitStyle = getStyle(12,1,true,false);
        createRow(unitStyle,0x190,"单位: XX科技有限公司",1,1,0,headNames.length-1);

        //第三行左边部分
        year = Integer.parseInt(bDate.substring(0,4));
        String month = bDate.substring(4,6);
        int m = Integer.parseInt(month)-1;
        Calendar   cal   =   Calendar.getInstance();
        cal.set(Calendar.YEAR,year);
        cal.set(Calendar.MONTH,m);//从0开始 0代表一月 11代表12月
        int   maxDate   =   cal.getActualMaximum(Calendar.DATE);

        sheet.addMergedRegion(new CellRangeAddress(2, 2, 0, 1));
        HSSFRow row = sheet.createRow(2);
        row.setHeight((short) 0x190);
        HSSFCell cell = row.createCell(0);
        cell.setCellStyle(getStyle(12,1,true,false));
        cell.setCellValue("时间:"+year+"年"+month+"月"+"01日至"+year+"年"+month+"月"+maxDate+"日");

        //第三行右边部分
        Date date = new Date();
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
        sheet.addMergedRegion(new CellRangeAddress(2, 2, 3, 5));
        HSSFCell cell2 = row.createCell(3);
        cell2.setCellStyle(getStyle(12,3,true,false));
        cell2.setCellValue("制表时间: "+sdf.format(date));

        //第四行表头
        boolean b = (headNames != null && headNames.length > 0);
        if (b) {
            HSSFRow row2 = sheet.createRow(3);
            row2.setHeight((short) 0x289);
            HSSFCell fcell = null;

            HSSFCellStyle cellStyle = getStyle(15,2,true,true); // 建立新的cell样式

            for (int i = 0; i < headNames.length; i++) {
                fcell = row2.createCell(i);

                fcell.setCellStyle(cellStyle);
                fcell.setCellValue(headNames[i]);
                if (colWidths != null && i < colWidths.length) {
                    sheet.setColumnWidth(i, 32 * colWidths[i]);
                }
            }
        }
        return b ? 4 : 3;  //从哪一行开始渲染表体
    }

    /**
     * 创建表体数据
     * @param data           表体数据
     * @param cellStyle      样式
     * @param startRow       开始行
     * @param colKeys        值对应map的key
     */
    private void setCellData(List<Map> data, HSSFCellStyle cellStyle, int startRow,
                             String[] colKeys) {
        // 创建数据
        HSSFRow row = null;
        HSSFCell cell = null;
        int i = startRow;

        if (data != null && data.size() > 0) {
            DecimalFormat df = new DecimalFormat("#0.00");
            for (Map<String, Object> rowData : data) {
                row = sheet.createRow(i);
                row.setHeight((short) 0x279);
                int j = 0;
                for (String key : colKeys) {
                    Object colValue = rowData.get(key);
                    if (key.equalsIgnoreCase("CITYNAME")){
                        colValue = colValue+"XX科技有限公司";
                    }else if (key.equalsIgnoreCase("ORDERSUM")||key.equalsIgnoreCase("TRANSFEE")||key.equalsIgnoreCase("ORDREALSUM")){
                        colValue = df.format(colValue);
                    }
                    cell = row.createCell(j);
                    cell.setCellStyle(cellStyle);
                    if (colValue != null) {
                        cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                        cell.setCellValue(colValue.toString());
                    }
                    j++;
                }
                i++;
            }
        }
    }

    /**
     * 创建表尾
     * @param size     
     * @param length
     */
    private void createTailCell(int size, int length) {
        HSSFCellStyle remarkStyle1 = getStyle(11,1,false,false);
        createRow(remarkStyle1,0x190,"经核对,确认以上数据真实无误。",size,size,0,length-2);

        HSSFCellStyle remarkStyle2 = getStyle(10,1,false,false);
        createRow(remarkStyle2,0x160,"(联系人:XXX;联系电话:13xxxxxxxx;邮箱:123456789@qq.com)",size+1,size+1,0,length-2);

        HSSFRow row3 = sheet.createRow(size+2);
        row3.setHeight((short) 0x379);

        sheet.addMergedRegion(new CellRangeAddress(size+3, size+3, 0, 1));
        HSSFRow row4 = sheet.createRow(size+3);
        row4.setHeight((short) 0x190);
        HSSFCell cell4 = row4.createCell(0);
        cell4.setCellStyle(getStyle(11,1,false,false));
        cell4.setCellValue("单位核对人:");

        sheet.addMergedRegion(new CellRangeAddress(size+3, size+3, 2, 4));
        HSSFCell cell15 = row4.createCell(2);
        cell15.setCellStyle(getStyle(11,1,false,false));
        cell15.setCellValue("单位制表人:");

        HSSFCellStyle dateStyle = getStyle(10,3,false,false);
        createRow(dateStyle,0x150,"公司公章                     ",size+8,size+8,0,length-2);

        createRow(dateStyle,0x150,year+"年  月   日",size+9,size+9,0,length-2);

    }


    // 测试
    public static void main(String[] args) throws IOException {
        Excel excel = new Excel();
        List<Map> data = new ArrayList<Map>();

        LinkedHashMap<String, Object> e = new LinkedHashMap<String, Object>();

        e.put("CITYNAME", "北京");
        e.put("ORDERCOUNT", "65");
        e.put("ORDERSUM", 930.38);
        e.put("TRANSFEE", 2.28);
        e.put("ORDREALSUM", 928.10);
        e.put("REMARK", "通过1");
        data.add(e);

        e = new LinkedHashMap<String, Object>();
        e.put("CITYNAME", "上海");
        e.put("ORDERCOUNT", "50");
        e.put("ORDERSUM", 850.34);
        e.put("TRANSFEE", 2.08);
        e.put("ORDREALSUM", 848.26);
        e.put("REMARK", "通过2");
        data.add(e);

        e = new LinkedHashMap<String, Object>();
        e.put("CITYNAME", "苏州");
        e.put("ORDERCOUNT", "10");
        e.put("ORDERSUM", 112.20);
        e.put("TRANSFEE", 2.20);
        e.put("ORDREALSUM", 55.00);
        e.put("REMARK", "通过3");
        data.add(e);

        e = new LinkedHashMap<String, Object>();
        e.put("CITYNAME", "南京");
        e.put("ORDERCOUNT", "26");
        e.put("ORDERSUM", 210.12);
        e.put("TRANSFEE", 0.51);
        e.put("ORDREALSUM", 2409.61);
        e.put("REMARK", "通过4");
        data.add(e);

        String[] headNames = { "单位名称", "收入笔数", "收入金额", "手续费(2.45‰)", "实际金额","备注" };
        String[] keys = { "CITYNAME",  "ORDERCOUNT", "ORDERSUM","TRANSFEE","ORDREALSUM","REMARK"};
        int colWidths[] = { 300, 200, 200, 200, 200,300 };

        String bDate = "201708";
        InputStream input = (excel.getExcelFile(data, "单位", headNames, keys, colWidths,bDate));

        File f = new File("f:\\excel.xls");
        if (f.exists())
            f.delete();
        f.createNewFile();
        FileOutputStream out = new FileOutputStream(f);
        HSSFWorkbook book = new HSSFWorkbook(input);
        book.write(out);
        out.flush();
        out.close();
    }

}

3合并规则

sheet.addMergedRegion(new CellRangeAddress(row1, row2, col1, col2));
对于row1行到row2行如果每行都有值则去第row1行的值为合并后的值;
col1列到col2的合并规则与行合并规则相同,取col1列的值为合并后的值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,724评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,104评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,142评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,086评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,076评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,914评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,220评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,871评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,318评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,834评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,951评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,574评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,162评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,162评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,383评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,349评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,652评论 2 343

推荐阅读更多精彩内容

  • 一个简单的例子,实现一个没有内容的workbook.xls文件 利用Maven引入相关的jar包 HSSF提供给用...
    Dl_毛良伟阅读 618评论 0 9
  • 使用首先需要了解他的工作原理 1.POI结构与常用类 (1)创建Workbook和Sheet (2)创建单元格 (...
    长城ol阅读 8,400评论 2 25
  • 转自链接 2.3.5 IF函数 2.3.6 CountIf和SumIf函数 2.3.7 Lookup函数 2.3....
    腿毛裤阅读 12,828评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 转自链接 目录 1.认识NPOI 2.使用NPOI生成xls文件 2.1创建基本内容 2.1.1创建Workboo...
    腿毛裤阅读 10,452评论 1 3