嘀嘀嘀!让你不在掉头发

相信好多小伙伴都遇到导出excel的时候,要合并单元个
那么它来了 它来了,直接都可以使用
平行丝滑导出,难道不香吗?

话不多说,直接怼

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Pattern;import com.alibaba.fastjson.JSON;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** @Author: Y* @Date: 2022/5/17 9:34*/
public class ExportExcel {/*** 创建excel文件** @param objData    数据* @param fileName   文件名* @param sheetName  sheet名* @param columns    表头* @param mergeIndex 需要合并的列号集合* @param request * @param response* @return*/public static int exportToExcelForXlsx(List<List<Object>> objData, String fileName, String sheetName, List<String> columns, List<Integer> mergeIndex, boolean isTree, HttpServletRequest request, HttpServletResponse response) {int flag = 0;Collections.sort(mergeIndex);//将列号排序// 创建工作薄XSSFWorkbook wb = new XSSFWorkbook();// sheet1XSSFSheet sheet1 = wb.createSheet(sheetName);//设置样式XSSFCellStyle style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);//水平对齐//表头sheet1.createFreezePane(0, 1);//冻结表头XSSFRow sheet1row1 = sheet1.createRow((short) 0);sheet1row1.setHeight((short) 480);//写入表头if (columns != null && columns.size() > 0) {for (int i = 0; i < columns.size(); i++) {String column = columns.get(i);//列XSSFCell cell = sheet1row1.createCell(i);cell.setCellValue(column);}}int dataSatrtIndex = 1;//数据开始行boolean isMerge = false;if (mergeIndex != null && mergeIndex.size() != 0) {isMerge = true;}//写入数据if (objData != null && objData.size() > 0) {Map<Integer, MergeModel> poiModels = new HashMap<Integer, MergeModel>();//循环写入表中数据int i = 0;for (; i < objData.size(); i++) {//数据行XSSFRow row = sheet1.createRow((short) (i + dataSatrtIndex));//行内循环,既单元格(列)List<Object> list = objData.get(i);DecimalFormat decimalFormat = new DecimalFormat("0.00");int j = 0;for (Object o : list) {//数据列String content = "";if (o != null) {if (o.toString().contains(".") && isNumeric(o.toString())) {content = decimalFormat.format(Float.valueOf(o.toString()));} else if (o.toString().contains("-") && o.toString().contains(":")) {content = String.valueOf(o).split("\\.")[0];} else {content = String.valueOf(o);}}if (isMerge && mergeIndex.contains(j)) {//如果该列需要合并MergeModel poiModel = poiModels.get(j);if (poiModel == null) {poiModel = new MergeModel();poiModel.setContent(content);poiModel.setRowIndex(i + dataSatrtIndex);poiModel.setCellIndex(j);poiModels.put(j, poiModel);} else {if (!poiModel.getContent().equals(content)) {//如果不同了,则将前面的数据合并写入if (isTree) {//此列向后的所有列都进行一次写入合并操作,并清空。//树结构中存在这种情况,a目录和b目录为同级目录,a目录下最后一个子目录和b目录下的第一个子目录名称相同,防止本来不应该合并的单元格被合并addMergedRegionValue(sheet1, poiModels, mergeIndex, i + dataSatrtIndex, poiModel.getCellIndex());} else {XSSFRow lastRow = sheet1.getRow(poiModel.getRowIndex());XSSFCell lastCell = lastRow.createCell(poiModel.getCellIndex());//创建列lastCell.setCellValue(poiModel.getContent());//合并单元格if (poiModel.getRowIndex() != i + dataSatrtIndex - 1) {sheet1.addMergedRegion(new CellRangeAddress(poiModel.getRowIndex(), i + dataSatrtIndex - 1, poiModel.getCellIndex(), poiModel.getCellIndex()));}}//将新数据存入poiModel.setContent(content);poiModel.setRowIndex(i + dataSatrtIndex);poiModel.setCellIndex(j);poiModels.put(j, poiModel);}}row.createCell(j);//创建单元格} else {//该列不需要合并//数据列XSSFCell cell = row.createCell(j);cell.setCellValue(content);}j++;}}//将最后一份存入if (poiModels != null && poiModels.size() != 0) {for (Integer key : poiModels.keySet()) {MergeModel poiModel = poiModels.get(key);XSSFRow lastRow = sheet1.getRow(poiModel.getRowIndex());XSSFCell lastCell = lastRow.getCell(poiModel.getCellIndex());lastCell.setCellValue(poiModel.getContent());//合并单元格if (poiModel.getRowIndex() != i + dataSatrtIndex - 1) {sheet1.addMergedRegion(new CellRangeAddress(poiModel.getRowIndex(), i + dataSatrtIndex - 1, poiModel.getCellIndex(), poiModel.getCellIndex()));}}}} else {flag = -1;}// 文件在浏览器中下载//设置固定列宽,poi的列宽设置有点操蛋,大概规律网上有不少版本自行百度//这里大概是143像素for (int i = 0; i < columns.size(); i++) {sheet1.setColumnWidth(i, 4550);}OutputStream os = null;try {// 创建一个普通输出流os = response.getOutputStream();fileName = "file.xls";// 请求浏览器打开下载窗口response.reset();response.setCharacterEncoding("UTF-8");// Content-disposition 告诉浏览器以下载的形式打开
//            String header = request.getHeader("User-Agent").toUpperCase();
//            if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {//                fileName = URLEncoder.encode(fileName, "utf-8");
//                fileName = fileName.replace("+", "%20"); // IE下载文件名空格变+号问题
//            } else {//                fileName = new String(fileName.getBytes(), "ISO8859-1");
//            }fileName = new String(fileName.getBytes(), "ISO8859-1");response.setHeader("Content-Disposition", "attachment; filename=" + fileName);// 要保存的文件名response.setContentType("application/octet-stream");
// 直接用数组缓冲输出流输出wb.write(os);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {wb.close();os.close();} catch (IOException e) {e.printStackTrace();}}
//       文件形式输出到磁盘中
//  FileOutputStream out = null;
//        try {//            String uuid = UUID.randomUUID().toString();
//            System.out.println(uuid);
//           out = new FileOutputStream("D:\\uploadPath\\download\\"+uuid+".xls");
            out = new FileOutputStream("E:\\" + fileName + ".xlsx");
//            wb.write(out);
//        } catch (Exception ex) {//            try {//                out.flush();
//                out.close();
//            } catch (IOException e) {//                flag = 0;
//                e.printStackTrace();
//            }
//        }return flag;}/*** 判断是不是数字** @param str* @return*/private static boolean isNumeric(String str) {if (str == null || str.length() == 0) {return false;}Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");return pattern.matcher(str).matches();}private static void addMergedRegionValue(XSSFSheet sheet, Map<Integer, MergeModel> poiModels, List<Integer> mergeIndex, int nowRowIndex, int nowCellIndex) {if (poiModels != null && poiModels.size() != 0 && mergeIndex != null && mergeIndex.size() != 0) {for (Integer index : mergeIndex) {if (index >= nowCellIndex) {MergeModel poiModel = poiModels.remove(index);//删除并获取valueif (poiModel != null) {XSSFRow lastRow = sheet.getRow(poiModel.getRowIndex());XSSFCell lastCell = lastRow.createCell(poiModel.getCellIndex());//创建列lastCell.setCellValue(poiModel.getContent());//合并单元格if (poiModel.getRowIndex() != nowRowIndex - 1) {sheet.addMergedRegion(new CellRangeAddress(poiModel.getRowIndex(), nowRowIndex - 1, poiModel.getCellIndex(), poiModel.getCellIndex()));}}}}}}public static void main(String[] args) {List<String> columns = new ArrayList<>();//标头columns.add("目录");columns.add("目录");columns.add("目录");columns.add("内容");String fileName = "文件名字";//文件名字String sheetName = "sheet名字";//sheet名字//内容数据List<List<Object>> exportData = new ArrayList<>();//行内的数据List<Object> rowData = new ArrayList<Object>();rowData.add("一级目录1");rowData.add("二级目录1");rowData.add("三级目录1");rowData.add("内容1");exportData.add(rowData);List<Object> rowData2 = new ArrayList<Object>();rowData2.add("一级目录1");rowData2.add("二级目录1");rowData2.add("三级目录1");rowData2.add("内容2");exportData.add(rowData2);List<Object> rowData3 = new ArrayList<Object>();rowData3.add("一级目录1");rowData3.add("二级目录1");rowData3.add("三级目录2");rowData3.add("内容3");exportData.add(rowData3);List<Object> rowData4 = new ArrayList<Object>();rowData4.add("一级目录1");rowData4.add("二级目录1");rowData4.add("三级目录2");rowData4.add("内容4");exportData.add(rowData4);List<Object> rowData5 = new ArrayList<Object>();rowData5.add("一级目录1");rowData5.add("二级目录2");rowData5.add("三级目录3");rowData5.add("内容5");exportData.add(rowData5);List<Object> rowData6 = new ArrayList<Object>();rowData6.add("一级目录1");rowData6.add("二级目录2");rowData6.add("三级目录3");rowData6.add("内容6");exportData.add(rowData6);String s = JSON.toJSONString(exportData);System.out.println(s);//需要合并的列号List<Integer> mergeIndex = new ArrayList<Integer>();mergeIndex.add(0);mergeIndex.add(1);
//        mergeIndex.add(2);
//        int flag = ExportExcel.exportToExcelForXlsx(exportData, fileName, sheetName, columns, mergeIndex, true, request, response);
//        System.out.println(flag);}
}

调用层代码

估计但凡有点经验的都能看懂,不做任何解释了

导出结果

原文链接 https://www.cnblogs.com/wdk2020/p/13204162.html

在最黑暗的那段人生,是我自己把自己拉出深渊。没有那个人,我就做那个人

Java poi 导出Excel并合并单元格 史上最强相关推荐

  1. java poi导出excel,合并单元格

    java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体:另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是 ...

  2. poi 导出Excel 动态 合并单元格

    public String arrearagePeriodExport(ArrearageParam param) {param.setPageNo(1);param.setPageSize(Inte ...

  3. Java POI 导出Excel,设置单元格无法编辑, 开启工作表保护后,依然可以筛选, 冻结行列不移动

    1. 设置单元格无法编辑 // 单元格样式锁定 不可编辑 CellStyle lockStyle = workbook.createCellStyle(); lockStyle.setLocked(t ...

  4. poi 导出excel 中合并单元格

    参数说明 CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) CellRangeAddress(起始行号,终止 ...

  5. Java 利用hutool工具实现导出excel并合并单元格

    Java 利用hutool工具实现导出excel并合并单元格 controller层调用service,就一个核心方法,没错就下面这个代码就能实现了.前提是项目里面要引用hutool包.把我这个复制到 ...

  6. Springboot导出excel,合并单元格示例

    原文链接:Springboot导出excel,合并单元格示例 更多文章,欢迎访问:Java知音,一个专注于技术分享的网站 以下用一个示例来说明springboot如何导出数据到excel. 首先引入M ...

  7. POI进行Excel的合并单元格数据处理

    POI进行Excel的合并单元格数据处理 近日接到一个要处理合并Excel单元格的上料表的需求,就到网上找了一些模板,发现有的技术大牛还是挺厉害的,对他们致以敬意. 合并单元格工具类 在这个类中将传入 ...

  8. easyexcel导出excel自定义合并单元格【动态表头和动态数据均可以自由合并】

    网上合并单元格的博客还是很多的,大家自行舍取吧.本文主要讲解固定与不固定的表头和内容如何合并 参考官网 https://easyexcel.opensource.alibaba.com/docs/cu ...

  9. java easypoi使用模板导出Excel,合并单元格

    工作几年,每年都有java数据导出Excel的需求,从最初的POI到公司封装的工具再到阿里的EasyExcel.总是有这个那个的小痛点,最近发现easypoi比较满足工作需求,可以很好的导出数据并处理 ...

  10. JAVA导出excel 动态合并单元格

    JAVA excel合并单元格原生poi 合并后的效果 直接上代码 (该方法为如果指定行的单元格里面的值一致则进行合并,直接粘贴使用即可) ** @param sheet* @param colIdx ...

最新文章

  1. 十七、生产者消费者问题
  2. 在Windows应用程序中使用正则表达式
  3. 013:ADS semihosting与硬件重定向(转)
  4. 字符串-字符串的查找和替换
  5. Scanner读取记事本文件内容为空的解决办法
  6. 【Flink】FLink checkpont 界面显示的含义
  7. 使用Arduino和超声波传感器实现简单测距
  8. Net-Snmp安装配置
  9. java微调器_java-更改微调器标题栏样式
  10. JQuery 实战第三讲:绚丽菜单
  11. 调试记录:基于NCN5120芯片的KNX-485桥接模块
  12. 华为服务器装系统识别不到硬盘,重装Windows10系统找不到硬盘的两种解决方法
  13. php 获取月初月末时间,php一个获取下月月初和月末的函数
  14. 网课研究生学术与职业素养讲座mooc答案
  15. 外贸用什么企业邮箱好?哪家企业邮箱安全又可靠?
  16. redis sadd 命令 以及 删除set集合或者单独删除set中的一/多条记录
  17. POI处理Excel中公式不能自动计算出来的问题
  18. oracle 加号和不加号,Oracle中连接与加号(+)的使用
  19. 3.暴力破解凯撒密码
  20. 微信看看对方是不是把你删除了

热门文章

  1. magma测试与安装,使用(含docker配置)
  2. 描述性物理海洋学--第一章学习笔记
  3. java 字符补位_JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码...
  4. 移动端输入密码时调用英文软键盘
  5. 几种css炫酷背景欣赏
  6. rough set_Rough.js使用Canvas和SVG制作手绘图形
  7. field automation,vif
  8. 【node】------node连接mongodb操作数据库------【巷子】
  9. IT4IT的前世今生
  10. IT6801FN图像质量调优