Java POI导出excel经典实现-交叉报表斜表头

简介: Java POI导出excel经典实现-交叉报表斜表头

Java使用poi组件导出excel报表,能导出excel报表的还可以使用jxl组件,但jxl想对于poi功能有限,jxl应该不能载excel插入浮动层图片,poi能很好的实现输出excel各种功能,介绍poi导出excel功能实现案例,算比较常用的功能实现以及导出excel需要注意的地方,采用的是poi-3.8-20120326.jar,poi-ooxml-3.8-20120326.jar,poi-scratchpad-3.8-20120326.jar

输出表格
poi输出excel最基本是输出table表格,下面是输出区域、总销售额(万元)、总利润(万元)简单的表格,创建HSSFWorkbook对象,用于将excel输出到输出流中

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("table"); //创建table工作薄
Object[][] datas = {{"区域", "总销售额(万元)", "总利润(万元)简单的表格"}, {"江苏省" , 9045, 2256}, {"广东省", 3000, 690}};
HSSFRow row;
HSSFCell cell;
for(int i = 0; i < datas.length; i++) {

row = sheet.createRow(i);//创建表格行
for(int j = 0; j < datas[i].length; j++) {
    cell = row.createCell(j);//根据表格行创建单元格
    cell.setCellValue(String.valueOf(datas[i][j]));
}

}
设置表格行高、列宽
有时表格文本比较多,需要设置表格的列宽度,在设置表格的行高与列宽时一定在创建全部的HSSFRow与HSSFCell之后,

即整个表格创建完成之后去设置,因为在单元格合并的时候,合并之前设置的宽度单元格会比设置的宽度更宽。sheet.setColumnWidth设置列宽值需要转换为excel的宽度值,使用工具类:MSExcelUtil,excel宽度并不是像素需要转换

HSSFWorkbook wb = new HSSFWorkbook();

HSSFSheet sheet = wb.createSheet("table"); //创建table工作薄

Object[][] datas = {{"区域", "总销售额(万元)", "总利润(万元)简单的表格"}, {"江苏省" , 9045, 2256}, {"广东省", 3000, 690}};

HSSFRow row;

HSSFCell cell;

for(int i = 0; i < datas.length; i++) {

row = sheet.createRow(i);//创建表格行

for(int j = 0; j < datas[i].length; j++) {

    cell = row.createCell(j);//根据表格行创建单元格

    cell.setCellValue(String.valueOf(datas[i][j]));

}

}

//创建表格之后设置行高与列宽

for(int i = 0; i < datas.length; i++) {

row = sheet.getRow(i);

row.setHeightInPoints(30);//设置行高

}

for(int j = 0; j < datas[0].length; j++) {

sheet.setColumnWidth(j, MSExcelUtil.pixel2WidthUnits(160)); //设置列宽

}
wb.write(new FileOutputStream("/Users/mike/table1.xls"));
设置excel单元格样式
单元格可以设置居左、居中、居右、上下居中、设置边框、设置边框颜色、设置单元格背景颜色等,excel设置单元格有一个HSSFCellStyle类可以设置样式,单元格颜色比较麻烦,excel颜色对应一个下标值,我们可以使用自定义颜色,但下标值从11开始,前1-10被poi已经使用,通过palette.setColorAtIndex方法将颜色与下标值对应,下面cellStyle.setFillForegroundColor(bgIndex)设置背景颜色时set下标值并不是颜色Color,一个下标值如11不能被重复设置颜色,否则excel单元格显示的都是黑色,如下背景颜色使用下标值bgIndex=11,边框颜色使用下标值

short colorIndex = 10;

HSSFPalette palette = wb.getCustomPalette();//自定义颜色

Color rgb = Color.GREEN;

short bgIndex = colorIndex ++; //背景颜色下标值

palette.setColorAtIndex(bgIndex, (byte) rgb.getRed(), (byte) rgb.getGreen(), (byte) rgb.getBlue());

short bdIndex = colorIndex ++; //边框颜色下标值

rgb = Color.BLACK;

palette.setColorAtIndex(bdIndex, (byte) rgb.getRed(), (byte) rgb.getGreen(), (byte) rgb.getBlue());

for(int i = 0; i < datas.length; i++) {

row = sheet.createRow(i);//创建表格行

for(int j = 0; j < datas[i].length; j++) {

    cell = row.createCell(j);//根据表格行创建单元格

    cell.setCellValue(String.valueOf(datas[i][j]));

    HSSFCellStyle cellStyle = wb.createCellStyle();

    cellStyle.setFillForegroundColor(bgIndex); //bgIndex 背景颜色下标值

    cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

    cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);

    cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);

    cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);

    cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

    //bdIndex 边框颜色下标值

    cellStyle.setBottomBorderColor(bdIndex);

    cellStyle.setLeftBorderColor(bdIndex);

    cellStyle.setRightBorderColor(bdIndex);

    cellStyle.setTopBorderColor(bdIndex);



    cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

    cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);



    cell.setCellStyle(cellStyle);

}

}
单元格文本设置字体样式
单元格文本可设置字体大小、颜色、斜体、粗体、下划线等。

HSSFCellStyle cellStyle = wb.createCellStyle();

HSSFFont font = wb.createFont();

font.setItalic(true);

font.setUnderline(HSSFFont.U_SINGLE);

font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

font.setFontHeightInPoints((short)14);

cellStyle.setFont(font);
合并单元格
sheet中可以类似html合并单元格,指定开始行(从0开始计算)、合并单元格最后行、开始列(从0开始)、合并单元格最后列四个参数值

CellRangeAddress region = new CellRangeAddress(0, // first row

    0, // last row

    0, // first column

    2 // last column

);

sheet.addMergedRegion(region);
单元格中加入图片
单元格中不仅是文本、数值、也可以加入图片,需要指定图片占用单元格开始行数、开始列数、末尾行数、末尾列数。

//加入图片

byte[] bt = FileUtils.readFileToByteArray(new File("/Users/mike/pie.png"));

int pictureIdx = wb.addPicture(bt, Workbook.PICTURE_TYPE_PNG);

CreationHelper helper = wb.getCreationHelper();

Drawing drawing = sheet.createDrawingPatriarch();

ClientAnchor anchor = helper.createClientAnchor();

anchor.setCol1(0); //图片开始列数

anchor.setRow1(4); //图片开始行数

anchor.setCol2(3); //图片结束列数

anchor.setRow2(25);//图片结束行数

drawing.createPicture(anchor, pictureIdx);
excel中插入浮动层图片类似html中div
excel中插入图片,poi导出excel似乎没有按绝对位置X、Y这样插入图片,可以行高和列宽计算X、Y值的大概的位置在哪个单元格中,然后类似插入图片,只指定图片开始行数、开始列数,picture.resize()会使图片依据图片实际大小进行扩展。

//加入图片

int pictureIdx = wb.addPicture(bt, Workbook.PICTURE_TYPE_PNG);

CreationHelper helper = wb.getCreationHelper();

Drawing drawing = sheet.createDrawingPatriarch();

ClientAnchor anchor = helper.createClientAnchor();

anchor.setCol1(0); //图片开始列数

anchor.setRow1(4); //图片开始行数

Picture picture = drawing.createPicture(anchor, pictureIdx);

picture.resize();
单元格中画斜线
excel单元格中画斜线另一篇有详细介绍:poiexcel斜线表头,长度转换MSExcelUtil,excel中单元格宽度和高度并不是像素值、ppt值,所以需要转换,MSExcelUtil是一个转换工具类,更多例子可参考:交叉报表制作(http://www.veryreport.com/handbookItem/doc-view-2000.html

public class MSExcelUtil {

public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;

public static final int UNIT_OFFSET_LENGTH = 7;

public static final int[] UNIT_OFFSET_MAP = new int[] { 0, 36, 73, 109, 146, 182, 219 };



/**

 * pixel units to excel width units(units of 1/256th of a character width)

 *

 * @param pxs

 * @return

 */

public static short pixel2WidthUnits(int pxs) {

    short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH));

    widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)];

    return widthUnits;

}



/**

 * excel width units(units of 1/256th of a character width) to pixel units

 *

 * @param widthUnits

 * @return

 */

public static int widthUnits2Pixel(int widthUnits) {

    int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) * UNIT_OFFSET_LENGTH;

    int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;

    pixels += Math.round(offsetWidthUnits

            / ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH));



    return pixels;

}

}
完整例子
poi导出excel源码

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import org.apache.commons.io.FileUtils;

import org.apache.poi.hssf.usermodel.HSSFCell;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import org.apache.poi.hssf.usermodel.HSSFFont;

import org.apache.poi.hssf.usermodel.HSSFPalette;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.ClientAnchor;

import org.apache.poi.ss.usermodel.CreationHelper;

import org.apache.poi.ss.usermodel.Drawing;

import org.apache.poi.ss.usermodel.Workbook;

import org.apache.poi.ss.util.CellRangeAddress;

public final class TestExportExcel {

public static void main(String[] args) throws Exception  {



    HSSFWorkbook wb = new HSSFWorkbook();

    HSSFSheet sheet = wb.createSheet("table");  //创建table工作薄

    Object[][] datas = {{"区域产品销售额","",""},{"区域", "总销售额(万元)", "总利润(万元)简单的表格"}, {"江苏省" , 9045,  2256}, {"广东省", 3000, 690}};

    HSSFRow row;

    HSSFCell cell;

     

    short colorIndex = 10;

    HSSFPalette palette = wb.getCustomPalette();

    Color rgb = Color.GREEN;

    short bgIndex = colorIndex ++;

    palette.setColorAtIndex(bgIndex, (byte) rgb.getRed(), (byte) rgb.getGreen(), (byte) rgb.getBlue());

    short bdIndex = colorIndex ++;

    rgb = Color.BLACK;

    palette.setColorAtIndex(bdIndex, (byte) rgb.getRed(), (byte) rgb.getGreen(), (byte) rgb.getBlue());

     

    for(int i = 0; i < datas.length; i++) {

        row = sheet.createRow(i);//创建表格行

        for(int j = 0; j < datas[i].length; j++) {

            cell = row.createCell(j);//根据表格行创建单元格

            cell.setCellValue(String.valueOf(datas[i][j]));

             

            HSSFCellStyle cellStyle = wb.createCellStyle();

            if(i == 0 || i == 1) {

                  cellStyle.setFillForegroundColor(bgIndex); //bgIndex 背景颜色下标值

                  cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

            }

           

            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

            //bdIndex 边框颜色下标值

            cellStyle.setBottomBorderColor(bdIndex);

            cellStyle.setLeftBorderColor(bdIndex);

            cellStyle.setRightBorderColor(bdIndex);

            cellStyle.setTopBorderColor(bdIndex);

             

            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

             

            if(i == datas.length - 1 && j == datas[0].length - 1) {

                HSSFFont font = wb.createFont();

                font.setItalic(true);

                font.setUnderline(HSSFFont.U_SINGLE);

                font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

                font.setFontHeightInPoints((short)14);

                cellStyle.setFont(font);

            }

            cell.setCellStyle(cellStyle);

        }

    }

     

    //加入图片

    byte[] bt = FileUtils.readFileToByteArray(new File("/Users/mike/pie.png"));

    int pictureIdx = wb.addPicture(bt, Workbook.PICTURE_TYPE_PNG);

    CreationHelper helper = wb.getCreationHelper();

    Drawing drawing = sheet.createDrawingPatriarch();

    ClientAnchor anchor = helper.createClientAnchor();

    anchor.setDx1(MSExcelUtil.pixel2WidthUnits(60));

    anchor.setDy1(MSExcelUtil.pixel2WidthUnits(60));

    anchor.setCol1(0);

    anchor.setRow1(4);

    anchor.setCol2(3);

    anchor.setRow2(25);

    drawing.createPicture(anchor, pictureIdx);

     

    //合并单元格

CellRangeAddress region = new CellRangeAddress(0, // first row
0, // last row
0, // first column
2 // last column
);

    sheet.addMergedRegion(region);

     

    //创建表格之后设置行高与列宽

for(int i = 0; i < datas.length; i++) {

        row = sheet.getRow(i);

        row.setHeightInPoints(30);

    }

    for(int j = 0; j < datas[0].length; j++) {

        sheet.setColumnWidth(j, MSExcelUtil.pixel2WidthUnits(160));

    }

    wb.write(new FileOutputStream("/Users/mike/table6.xls"));

}   

}

相关文章
|
6天前
|
Java API Apache
Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
【10月更文挑战第29天】Java编程如何读取Word文档里的Excel表格,并在保存文本内容时保留表格的样式?
34 5
|
16天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
118 1
|
6天前
|
Java API Apache
|
9天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
21 4
|
27天前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
192 0
|
2月前
|
存储 Java
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
44 2
|
1月前
|
Java Apache
Apache POI java对excel表格进行操作(读、写) 有代码!!!
文章提供了使用Apache POI库在Java中创建和读取Excel文件的详细代码示例,包括写入数据到Excel和从Excel读取数据的方法。
34 0
|
2月前
|
Java Apache Maven
Java中使用poi+poi-tl实现根据模板导出word文档
这个过程不仅简化了文档生成的工作,而且保证了生成文档的一致性与准确性,特别适合于那些需要生成大量文档的自动化场景。通过以上步骤,Java开发人员可以实现高效、可靠的Word文档导出功能。
1169 0
|
9天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
4天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####

热门文章

最新文章