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])); } } wb.write(new FileOutputStream("/Users/mike/table.xls"));
設置表格行高、列寬
有時表格文本比較多,需要設置表格的列寬度,在設置表格的行高與列寬時一定在創建全部的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,邊框顏色使用下標值bdIndex=12
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);
單元格中加入圖片
單元格中不僅是文本、數值、也可以加入圖片,需要指定圖片占用單元格開始行數、開始列數、末尾行數、末尾列數。
支持png、jpeg、emf等
//加入圖片 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值的大概的位置在哪個單元格中,
然后類似(6)中插入圖片,只指定圖片開始行數、開始列數,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單元格中畫斜線另一篇有詳細介紹
長度轉換MSExcelUtil
excel中單元格寬度和高度並不是像素值、ppt值,所以需要轉換,MSExcelUtil是一個轉換工具類
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")); } }