1.需求說明
在企業級應用開發中,Excel報表是一種最常見的報表需求。Excel報表開發一般分為兩種形式:
1、為了方便操作,基於Excel的報表批量上傳數據
2、通過java代碼生成Excel報表。
2.Excel報表概述
目前市面上的Excel分為兩大版本Excel2003和Excel2007及以上兩個版本,它們區別如下:
3.常見的Excel操作工具
Java中常見的用來操作Excl的方式一般有2種:JXL和POI。
JXL只能對Excel進行操作,屬於比較老的框架,它只支持到Excel 95-2000的版本。現在已經停止更新和維護。
POI是apache的項目,可對微軟的Word,Excel,Ppt進行操作,包括office2003和2007,Excl2003和2007。poi現在一
直有更新。所以現在主流使用POI。
4.POI是什么
Apache POI是Apache軟件基金會的開源項目,由Java編寫的免費開源的跨平台的 Java API,Apache POI提供API給
Java語言操作Microsoft Office的功能。
Apache POI是目前最流行的操作Microsoft Office的API組件,借助POI可以方便的完成諸如:數據報表生成,數據批
量上傳,數據備份等工作
5.POI入門
搭建環境
引入坐標
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.0.1</version> </dependency>
API說明
HSSF提供讀寫Microsoft Excel XLS格式檔案的功能。 2003版本
XSSF提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能。2007版本
創建Excel
public class PoiTest01 { /** * 創建一個excel * 創建excel: * 1.創建工作簿 * 2.創建sheet * 3.創建行對象 * 4.創建單元格 * 5.對單元格賦值 * 6.設置樣式 * 7.下載 */ @Test public void test() throws Exception { //1.創建一個工作簿 //Workbook wb = new HSSFWorkbook(); //處理excel2003版本 .xls Workbook wb = new XSSFWorkbook();//處理excel2007及以上版本 .xlsx //new SXSSFWorkbook();// 處理大數據量excel報表對象 //2.創建sheet Sheet sheet = wb.createSheet("abc"); //3.創建行對象 Row row = sheet.createRow(1);//接受參數 ,數組下標 //4.創建單元格 Cell cell = row.createCell(1);//數組下表 //5.設置單元格內容 cell.setCellValue("大冪冪"); //設置樣式 /** * 1.創建樣式對象 * 2.通過樣式對象指定樣式 * 3.配置單元個樣式 */2.3、讀取excel CellStyle cellStyle = wb.createCellStyle(); //通過樣式對象指定樣式 cellStyle.setBorderTop(BorderStyle.THIN); //細線 cellStyle.setBorderBottom(BorderStyle.THIN); //細線 cellStyle.setBorderLeft(BorderStyle.THIN); //細線 cellStyle.setBorderRight(BorderStyle.THIN); //細線 //字體 對象 Font font = wb.createFont(); font.setFontName("華文行楷"); font.setFontHeightInPoints((short)26);//字號 cellStyle.setFont(font); cell.setCellStyle(cellStyle); //指定行高和列寬 sheet.setColumnWidth(1,20*256); //列寬 row.setHeightInPoints(30); //6.將excel保存到本地磁盤中 FileOutputStream fos = new FileOutputStream("E:\\text.xlsx"); wb.write(fos); fos.close(); } }
讀取Excel
讀取如下報表
/** * 加載excel文件,並讀取內容 */ public class PoiTest02 { @Test public void test() throws Exception { //1.根據excel文件加載工作簿 Workbook wb = new XSSFWorkbook("E:\\demo1.xlsx"); //2.讀取第一個sheet Sheet sheet = wb.getSheetAt(0);//數組下標 //3.循環sheet中的每一行 //sheet.getLastRowNum 獲取最后一行的數組下標 for(int i=0;i<sheet.getLastRowNum()+1;i++) { Row row = sheet.getRow(i); //row.getLastCellNum() 獲取最大行數 //4.讀取行中的每一個單元格 String str = ""; for(int j=0;j<row.getLastCellNum();j++) { Cell cell = row.getCell(j); //5.獲取單元格中的數據 if(cell != null) { str += getCellValue(cell); } } System.out.println(str); } } public Object getCellValue(Cell cell) { /** * 獲取單元格的類型 */ CellType type = cell.getCellType(); Object result = null; switch (type) { case STRING:{ result = cell.getStringCellValue();//獲取string類型數據 break; } case NUMERIC:{ /** * 判斷 */ if(DateUtil.isCellDateFormatted(cell)) { //日期格式 result = cell.getDateCellValue(); }else{ //double類型 result = cell.getNumericCellValue(); //數字類型 } break; } case BOOLEAN:{ result = cell.getBooleanCellValue();//獲取boolean類型數據 break; } default:{ break; } } return result; } }
思考
Excel報表打印項目實際操作上遇到的問題
從數據庫查詢出來的Excel數據並不一定是來自於一張表,可能來自於多張表
解決:我們需要自定義一個javaBean實體,從數據庫查詢出來返回到實體中
當然sql語句還是很重要的:
我們運用多表聯查,並且可能要一些表單創建時間查詢,這里我們
用到了MySql的日期函數
場景
附一條sql語句
<!--查詢報表數據-->
<select id="findByCreateTime" parameterType="map" resultType="cn.jia.domain.vo.ContractProductVo">
SELECT
c.custom_name customName,
c.contract_no contractNo,
cp.product_no productNo,
cp.cnumber cnumber,
cp.factory_name factoryName,
c.delivery_period deliveryPeriod,
c.ship_time shipTime,
c.trade_terms tradeTerms
FROM co_contract c,co_contract_product cp
WHERE c.id = cp.contract_id
and c.company_id = #{companyid}
AND DATE_FORMAT(create_time,'%Y-%m') = #{inputDate}
</select>
附Mysql日期函數
MySQL DATE_FORMAT() 函數
定義和用法
DATE_FORMAT() 函數用於以不同的格式顯示日期/時間數據。
語法
DATE_FORMAT(date,format)
date 參數是合法的日期。format 規定日期/時間的輸出格式。
可以使用的格式有:
格式 |
描述 |
%a |
縮寫星期名 |
%b |
縮寫月名 |
%c |
月,數值 |
%D |
帶有英文前綴的月中的天 |
%d |
月的天,數值(00-31) |
%e |
月的天,數值(0-31) |
%f |
微秒 |
%H |
小時 (00-23) |
%h |
小時 (01-12) |
%I |
小時 (01-12) |
%i |
分鍾,數值(00-59) |
%j |
年的天 (001-366) |
%k |
小時 (0-23) |
%l |
小時 (1-12) |
%M |
月名 |
%m |
月,數值(00-12) |
%p |
AM 或 PM |
%r |
時間,12-小時(hh:mm:ss AM 或 PM) |
%S |
秒(00-59) |
%s |
秒(00-59) |
%T |
時間, 24-小時 (hh:mm:ss) |
%U |
周 (00-53) 星期日是一周的第一天 |
%u |
周 (00-53) 星期一是一周的第一天 |
%V |
周 (01-53) 星期日是一周的第一天,與 %X 使用 |
%v |
周 (01-53) 星期一是一周的第一天,與 %x 使用 |
%W |
星期名 |
%w |
周的天 (0=星期日, 6=星期六) |
%X |
年,其中的星期日是周的第一天,4 位,與 %V 使用 |
%x |
年,其中的星期一是周的第一天,4 位,與 %v 使用 |
%Y |
年,4 位 |
%y |
年,2 位 |
實例
下面的腳本使用 DATE_FORMAT() 函數來顯示不同的格式。我們使用 NOW() 來獲得當前的日期/時間:
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
DATE_FORMAT(NOW(),'%m-%d-%Y')
DATE_FORMAT(NOW(),'%d %b %y')
DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
結果類似:
Dec 29 2008 11:45 PM
12-29-2008
29 Dec 08
29 Dec 2008 16:25:46.635