apache poi根据模板导出excel

需要预先新建编辑好一个excel文件,设置好样式。

编辑好输出的数据,根据excel坐标一一对应。

支持列表数据输出,列表中列合并。

代码如下:

package com.icourt.util;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 描述:poi根据模板导出excel,根据excel坐标赋值,如(B1)
 */
public class ExcelExportUtil {

    //模板map
    private Map<String, Workbook> tempWorkbook = new HashMap<String, Workbook>();
    //模板输入流map
    private Map<String, InputStream> tempStream = new HashMap<String, InputStream>();

    /**
     * 功能:按模板向Excel中相应地方填充数据
     */
    public void writeData(String templateFilePath, Map<String, Object> dataMap, int sheetNo) throws IOException, InvalidFormatException {
        if (dataMap == null || dataMap.isEmpty()) {
            return;
        }
        //读取模板
        Workbook wbModule = getTempWorkbook(templateFilePath);
        //数据填充的sheet
        Sheet wsheet = wbModule.getSheetAt(sheetNo);

        for (Entry<String, Object> entry : dataMap.entrySet()) {
            String point = entry.getKey();
            Object data = entry.getValue();

            TempCell cell = getCell(point, data, wsheet);
            //指定坐标赋值
            setCell(cell, wsheet);
        }

        //设置生成excel中公式自动计算
        wsheet.setForceFormulaRecalculation(true);
    }

    /**
     * 功能:按模板向Excel中列表填充数据.只支持列合并
     */
    public void writeDateList(String templateFilePath, String[] heads, List<Map<Integer, Object>> datalist, int sheetNo) throws IOException, InvalidFormatException {
        if (heads == null || heads.length <= 0 || CollectionUtils.isEmpty(datalist)) {
            return;
        }
        //读取模板
        Workbook wbModule = getTempWorkbook(templateFilePath);
        //数据填充的sheet
        Sheet wsheet = wbModule.getSheetAt(sheetNo);

        //列表数据模板cell
        List<TempCell> tempCells = new ArrayList<TempCell>(heads.length);
        for (String point : heads) {
            TempCell tempCell = getCell(point, null, wsheet);
            //取得合并单元格位置  -1:表示不是合并单元格
            int pos = isMergedRegion(wsheet, tempCell.getRow(), tempCell.getColumn());
            if (pos > -1) {
                CellRangeAddress range = wsheet.getMergedRegion(pos);
                tempCell.setColumnSize(range.getLastColumn() - range.getFirstColumn());
            }
            tempCells.add(tempCell);
        }
        //赋值
        for (int i = 0; i < datalist.size(); i++) {//数据行
            Map<Integer, Object> dataMap = datalist.get(i);
            for (int j = 0; j < tempCells.size(); j++) {//列
                TempCell tempCell = tempCells.get(j);
                tempCell.setData(dataMap.get(j + 1));
                setCell(tempCell, wsheet);
                tempCell.setRow(tempCell.getRow() + 1);
            }
        }
    }

    /**
     * 功能:获取输入工作区
     */
    private Workbook getTempWorkbook(String templateFilePath) throws IOException, InvalidFormatException {
        if (!tempWorkbook.containsKey(templateFilePath)) {
            InputStream inputStream = getInputStream(templateFilePath);
            tempWorkbook.put(templateFilePath, WorkbookFactory.create(inputStream));
        }
        return tempWorkbook.get(templateFilePath);
    }

    /**
     * 功能:获得模板输入流
     */
    private InputStream getInputStream(String templateFilePath) throws FileNotFoundException {
        if (!tempStream.containsKey(templateFilePath)) {
            tempStream.put(templateFilePath, new FileInputStream((templateFilePath)));
        }
        return tempStream.get(templateFilePath);
    }

    /**
     * 功能:获取单元格数据,样式(根据坐标:B3)
     */
    private TempCell getCell(String point, Object data, Sheet sheet) {
        TempCell tempCell = new TempCell();

        //得到列   字母
        String lineStr = "";
        String reg = "[A-Z]+";
        Pattern p = Pattern.compile(reg);
        Matcher m = p.matcher(point);
        while (m.find()) {
            lineStr = m.group();
        }
        //将列字母转成列号  根据ascii转换
        char[] ch = lineStr.toCharArray();
        int column = 0;
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            int post = ch.length - i - 1;
            int r = (int) Math.pow(10, post);
            column = column + r * ((int) c - 65);
        }
        tempCell.setColumn(column);

        //得到行号
        reg = "[1-9]+";
        p = Pattern.compile(reg);
        m = p.matcher(point);
        while (m.find()) {
            tempCell.setRow((Integer.parseInt(m.group()) - 1));
        }

        //获取模板指定单元格样式,设置到tempCell(写列表数据的时候用)
        Row rowIn = sheet.getRow(tempCell.getRow());
        if (rowIn == null) {
            rowIn = sheet.createRow(tempCell.getRow());
        }
        Cell cellIn = rowIn.getCell(tempCell.getColumn());
        if (cellIn == null) {
            cellIn = rowIn.createCell(tempCell.getColumn());
        }
        tempCell.setCellStyle(cellIn.getCellStyle());
        tempCell.setData(data);
        return tempCell;
    }

    /**
     * 功能:给指定坐标单元格赋值
     */
    private void setCell(TempCell tempCell, Sheet sheet) {
        if (tempCell.getColumnSize() > -1) {
            CellRangeAddress rangeAddress = mergeRegion(sheet, tempCell.getRow(), tempCell.getRow(), tempCell.getColumn(), tempCell.getColumn() + tempCell.getColumnSize());
            setRegionStyle(tempCell.getCellStyle(), rangeAddress, sheet);
        }

        Row rowIn = sheet.getRow(tempCell.getRow());
        if (rowIn == null) {
            copyRows(tempCell.getRow() - 1, tempCell.getRow() - 1, tempCell.getRow(), sheet);//复制上一行
            rowIn = sheet.getRow(tempCell.getRow());
        }
        Cell cellIn = rowIn.getCell(tempCell.getColumn());
        if (cellIn == null) {
            cellIn = rowIn.createCell(tempCell.getColumn());
        }
        //根据data类型给cell赋值
        if (tempCell.getData() instanceof String) {
            cellIn.setCellValue((String) tempCell.getData());
        } else if (tempCell.getData() instanceof Integer) {
            cellIn.setCellValue((int) tempCell.getData());
        } else if (tempCell.getData() instanceof Double) {
            cellIn.setCellValue((double) tempCell.getData());
        } else {
            cellIn.setCellValue((String) tempCell.getData());
        }
        //样式
        if (tempCell.getCellStyle() != null && tempCell.getColumnSize() == -1) {
            cellIn.setCellStyle(tempCell.getCellStyle());
        }
    }

    /**
     * 功能:写到输出流并移除资源
     */
    public void writeAndClose(String templateFilePath, OutputStream os) throws IOException, InvalidFormatException {
        if (getTempWorkbook(templateFilePath) != null) {
            getTempWorkbook(templateFilePath).write(os);
            tempWorkbook.remove(templateFilePath);
        }
        if (getInputStream(templateFilePath) != null) {
            getInputStream(templateFilePath).close();
            tempStream.remove(templateFilePath);
        }
    }

    /**
     * 功能:判断指定的单元格是否是合并单元格
     */
    private Integer isMergedRegion(Sheet sheet, int row, int column) {
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    return i;
                }
            }
        }
        return -1;
    }

    /**
     * 功能:合并单元格
     */
    private CellRangeAddress mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        CellRangeAddress rang = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        sheet.addMergedRegion(rang);
        return rang;
    }

    /**
     * 功能:设置合并单元格样式
     */
    private void setRegionStyle(CellStyle cs, CellRangeAddress region, Sheet sheet) {
        for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) row = sheet.createRow(i);
            for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    cell = row.createCell(j);
                    cell.setCellValue("");
                }
                cell.setCellStyle(cs);
            }
        }
    }

    /**
     * 功能:copy rows
     */
    private void copyRows(int startRow, int endRow, int pPosition, Sheet sheet) {
        int pStartRow = startRow - 1;
        int pEndRow = endRow - 1;
        int targetRowFrom;
        int targetRowTo;
        int columnCount;
        CellRangeAddress region = null;
        int i;
        int j;
        if (pStartRow == -1 || pEndRow == -1) {
            return;
        }
        // 拷贝合并的单元格
        for (i = 0; i < sheet.getNumMergedRegions(); i++) {
            region = sheet.getMergedRegion(i);
            if ((region.getFirstRow() >= pStartRow)
                    && (region.getLastRow() <= pEndRow)) {
                targetRowFrom = region.getFirstRow() - pStartRow + pPosition;
                targetRowTo = region.getLastRow() - pStartRow + pPosition;
                CellRangeAddress newRegion = region.copy();
                newRegion.setFirstRow(targetRowFrom);
                newRegion.setFirstColumn(region.getFirstColumn());
                newRegion.setLastRow(targetRowTo);
                newRegion.setLastColumn(region.getLastColumn());
                sheet.addMergedRegion(newRegion);
            }
        }
        // 设置列宽
        for (i = pStartRow; i <= pEndRow; i++) {
            Row sourceRow = sheet.getRow(i);
            columnCount = sourceRow.getLastCellNum();
            if (sourceRow != null) {
                Row newRow = sheet.createRow(pPosition - pStartRow + i);
                newRow.setHeight(sourceRow.getHeight());
                for (j = 0; j < columnCount; j++) {
                    Cell templateCell = sourceRow.getCell(j);
                    if (templateCell != null) {
                        Cell newCell = newRow.createCell(j);
                        copyCell(templateCell, newCell);
                    }
                }
            }
        }
    }

    /**
     * 功能:copy cell,不copy值
     */
    private void copyCell(Cell srcCell, Cell distCell) {
        distCell.setCellStyle(srcCell.getCellStyle());
        if (srcCell.getCellComment() != null) {
            distCell.setCellComment(srcCell.getCellComment());
        }
        int srcCellType = srcCell.getCellType();
        distCell.setCellType(srcCellType);
    }

    /**
     * 描述:临时单元格数据
     */
    class TempCell {
        private int row;
        private int column;
        private CellStyle cellStyle;
        private Object data;
        //用于列表合并,表示几列合并
        private int columnSize = -1;

        public int getColumn() {
            return column;
        }

        public void setColumn(int column) {
            this.column = column;
        }

        public int getRow() {
            return row;
        }

        public void setRow(int row) {
            this.row = row;
        }

        public CellStyle getCellStyle() {
            return cellStyle;
        }

        public void setCellStyle(CellStyle cellStyle) {
            this.cellStyle = cellStyle;
        }

        public Object getData() {
            return data;
        }

        public void setData(Object data) {
            this.data = data;
        }

        public int getColumnSize() {
            return columnSize;
        }

        public void setColumnSize(int columnSize) {
            this.columnSize = columnSize;
        }
    }

    public static void main(String[] args) throws FileNotFoundException, IOException, InvalidFormatException {
        String templateFilePath = ExcelExportUtil.class.getClassLoader().getResource("plugin/ProTiming.xlsx").getPath();
        File file = new File("/Users/sql/Downloads/test/data.xlsx");
        OutputStream os = new FileOutputStream(file);

        ExcelExportUtil excel = new ExcelExportUtil();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("B1", "03_Alpha_项目工作时间统计表");
        dataMap.put("B2", "统计时间:2017/01/01 - 2017/03/31");

        excel.writeData(templateFilePath, dataMap, 0);

        List<Map<Integer, Object>> datalist = new ArrayList<Map<Integer, Object>>();
        Map<Integer, Object> data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");

        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);

        data = new HashMap<Integer, Object>();
        data.put(1, "3/10/17");
        data.put(2, "18:50");
        data.put(3, "19:00");
        data.put(4, "李子鹏");
        data.put(5, "新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用");
        data.put(6, "代码开发");
        data.put(7, "3.17");
        datalist.add(data);
        data = new HashMap<Integer, Object>();
        data.put(1, "");
        data.put(2, "");
        data.put(3, "");
        data.put(4, "");
        data.put(5, "");
        data.put(6, "");
        data.put(7, "");
        datalist.add(data);

        String[] heads = new String[]{"B4", "C4", "D4", "E4", "F4", "G4", "H4"};
        excel.writeDateList(templateFilePath, heads, datalist, 0);

        //写到输出流并移除资源
        excel.writeAndClose(templateFilePath, os);

        os.flush();
        os.close();
    }

}

大体思路:

最主要是制作好模版

代码根据模版,读取设置好的列的格式,在循环数据行,读取模版中的对应的行,存在该行就取得,不存在看是否需要copy某一行,不需要就手动创建无制定格式的行,后面在为该行的每一列对应的给个单元格制定格式和数据。

时间: 2024-10-11 13:12:53

apache poi根据模板导出excel的相关文章

POI通过模板导出EXCEL文件

一般的EXCEL导出使用POI先创建一个HSSFWorkbook,然后通过不断创建HSSFRow,HSSFCell后设置单元格内容便可以完成导出. 这次在项目中需要用到模板,导出的内容包括(1.模板中的内容.样式.2.自己需要新增的内容.样式.),还需要设置单元格的样式,在网上搜了一些blog,完成后记录一下. 分析这次需求,最关键的就是如何获取到填充了模板的新HSSFWorkbook,如果获取到它,我们可以熟练的往里面添加内容. 1 File fi = new File("F:/usr/use

java后台poi根据模板导出excel

public class ExcelUtils { private static final String INSPECTIONRECORD_SURFACE_TEMPLET_PATH = "download\\template\\materialList.xlsx"; private static XSSFCellStyle cellstyle = null; public static void exportBom(HttpServletRequest request, HttpSe

Java使用POI实现数据导出excel报表

在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅仅简单的读取office中的数据.尤其是在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作.而数据导出的格式一般是EXCEL或者PDF .所以今天我们来简单看一下利用Apache  POI实现数据库中数据导出excel报表.在java中有很多实现数据导出excel报表的第三方jar包.但在比较了一下感觉还是POI相对来

Apache POI – Reading and Writing Excel file in Java

来源于:https://www.mkyong.com/java/apache-poi-reading-and-writing-excel-file-in-java/ In this article, we will discuss about how to read and write an excel file using Apache POI 1. Basic definitions for Apache POI library This section briefly describe a

aspose.cells根据模板导出excel

又隔十多天没写博客了,最近都在忙项目的事情,公司人事变动也比较大,手头上就又多了一个项目.最近做用aspose.cells根据模板导出excel报价单的功能,顺便把相关的核心记下来,先上模板和导出的效果图吧,如下: 导出效果图(看到产品图,打不死的程(diao)序(si)员(猿)骚动吧,有没有不禁看了看自己粗大的右手): (其中红色框框起来的是动态填充的内容,工作薄名(产品信息)也是动态输出的) 模板如下: 大概流程是这样,先把需要输出到excel的内容存到一个model里面,然后把该model

C#使用模板导出Excel

前言:此随笔仅供自己学习,如有不足请指出 在某些情况导出的时候,会有很复杂的表头或者样式,如果靠代码去调整的话回很麻烦,需要写很多代码,这个时候可以预先设置好表格,这样就方便灵活很多. /// <summary> /// 使用模板导出Excel /// </summary> /// <param name="listEntity">数据集</param> /// <param name="path">路径&

WeihanLi.Npoi 根据模板导出Excel

WeihanLi.Npoi 根据模板导出Excel Intro 原来的导出方式比较适用于比较简单的导出,每一条数据在一行,数据列虽然自定义程度比较高,如果要一条数据对应多行就做不到了,于是就想支持根据模板导出,在 1.8.0 版本中引入了根据模板导出的功能 使用示例 示例模板 模板规划的可以有三种数据: Global:一个是导出的时候可以指定一些参数,作为 Global 参数,默认参数格式使用: $(Global:PropName) 的格式 Header:配置的对应属性的显示名称,默认是属性名称

使用apache的poi实现导入导出excel

1.jar包:poi-3.14-20160307.jar.poi-ooxml-3.14-20160307.jar 2.导入(本例实现了解析excel生成List): @Override public Map<String, Object> parseExcel(String fileName) { // 1.准备返回的变量 Map<String, Object> resultMap = new HashMap<String, Object>(); String mess

poi 架包导出excel,并下载

导出excel在许多系统中都有应用到,这里以两个简单例子作为介绍: 1.导入poi-3.9.jar,可以在官网下载http://poi.apache.org . 2.先写一个简单的测试类,里面有详细的解释,代码如下: 1 import java.io.FileOutputStream; 2 import java.io.IOException; 3 import org.apache.poi.hssf.usermodel.HSSFCell; 4 import org.apache.poi.hss