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某一行,不需要就手动创建无制定格式的行,后面在为该行的每一列对应的给个单元格制定格式和数据。
apache poi根据模板导出excel的更多相关文章
- POI通过模板导出EXCEL文件
一般的EXCEL导出使用POI先创建一个HSSFWorkbook,然后通过不断创建HSSFRow,HSSFCell后设置单元格内容便可以完成导出. 这次在项目中需要用到模板,导出的内容包括(1.模板中 ...
- 使用Apache poi来编写导出excel的工具类
在JavaWeb开发的需求中,我们会经常看到导出excel的功能需求,然后java并没有提供操作office文档的功能,这个时候我们就需要使用额外的组件来帮助我们完成这项功能了. 很高兴Apache基 ...
- java后台poi根据模板导出excel
public class ExcelUtils { private static final String INSPECTIONRECORD_SURFACE_TEMPLET_PATH = " ...
- poi根据excel模板导出Excel
/****单元格值对象**/public class Cells { /*** * 行 */ private int row; /** * 列 */ private int column; /** * ...
- Java无模板导出Excel,Apache-POI插件实现
开发环境 jdk 1.8 Maven 3.6 Tomcat 8.5 SpringBoot 2.1.4.RELEASE Apache-POI 3.6 Idea 注意: 我是在现有的基于SpringBoo ...
- Java中使用poi导入、导出Excel
一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际 ...
- Java使用POI实现数据导出excel报表
Java使用POI实现数据导出excel报表 在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅 ...
- POI导入和导出Excel总结
POI导入和导出Excel总结 POI使用总结 1.POI读取Excel 打开工作簿的方式有以下两种简单的应用,POI读取和输出工作簿文件都可以通过以下两种方式来声明: //通过输入流的方式打开本 ...
- aspose.cells根据模板导出excel
又隔十多天没写博客了,最近都在忙项目的事情,公司人事变动也比较大,手头上就又多了一个项目.最近做用aspose.cells根据模板导出excel报价单的功能,顺便把相关的核心记下来,先上模板和导出的效 ...
随机推荐
- 文本编辑器 未完成 Treap
#include<bits/stdc++.h> using namespace std; const int maxn = 2e6+1e5; unsigned int SEED = 17; ...
- springboot(五)-使用Redis
Redis服务器 springboot要使用redis,首先当然要确保redis服务器能够正常跑起来. pom.xml 这里添加redis的依赖,当然也是springboot集成好的. <!-- ...
- window 中安装 hadoop
win10上部署Hadoop-2.7.3——非Cygwin.非虚拟机 开始接触Hadoop,听人说一般都是在Lunix下部署Hadoop,但是本人Lunix不是很了解,所以Google以下如何在W ...
- Oracle分组函数之CUBE魅力
Oracle的CUBE与ROLLUP功能很相似,也是在数据统计分析领域的一把好手. 关于ROLLUP的查询统计功能请参考文章<Oracle分组函数之ROLLUP魅力>(http://www ...
- Android 自动分析apk加固方式
本实例只对apk中lib文件夹中的文件进行分析import java.io.File;import java.io.IOException;import java.util.ArrayList;imp ...
- 多租户概念以及FreeLink多租户设计思想
多租户实现思想 多租户技术的实现重点,在于不同租户间应用程序环境的隔离(application context isolation)以及数据的隔离(data isolation),以维持不同租户间应用 ...
- js数组方法详解
Array对象的方法-25个 /*js数组方法详解 */ /* * 1 concat() 用于连接多个数组或者值-------------- * 2 copyWithin() 方法用于从数组的指定位置 ...
- ABP Zero集成微信小程序登录
首先是ABPZero的第三方登录模块,通过调用第三方的登录接口返回用户信息,再交给ABP的登录验证模块去执行对应的登录注册. 涉及的数据库表主要是这两个表,AbpUsers存储了用户信息,AbpUse ...
- Beam概念学习系列之PTransform数据处理
不多说,直接上干货! PTransform数据处理 PTransform对PCollection进行并行处理,每次处理1条,例如Filter过滤.Groupby分组.Combine统计.Join关联等 ...
- Oracle使用sys登录时报错ORA-28009解决方法
情况一:使用sqlplus登录: 正常输入用户名的口令,就会报错,因为SYS是在数据库之外的超级管理员,所以我们在登录的时候 要在输入口令:口令+as sysdba(比如:123456 as sysd ...