根據模板導出Excel報表並復制模板生成多個Sheet頁


因為最近用報表導出比較多,所有就提成了一個工具類,本工具類使用的場景為  根據提供的模板來導出Excel報表 

並且可根據提供的模板Sheet頁進行復制 從而實現多個Sheet頁的需求,

使用本工具類時,如果需求是每個Sheet頁中的數據都不一致,但是表格樣式和模板都一樣

那么只需要在實際情況中根據 sql 來查詢要添加的數據源 (只需更改數據源即可)

采用的技術為 POI 導出,因為類的緣故,目前只支持2003版本的Excel.

使用前請先下載相應jar包!

后期有時間的話會進行進一步完善,初次寫工具類,若有不完善的地方還請包涵!

先看看模板樣式和運行結果,然后直接上代碼

這是Excel的模板樣式

 

這是導出結果

 

具體實現看demo

package com.sgcc.xyz.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
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.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import com.sgcc.uap.persistence.impl.HibernateDaoImpl;

/**
 * 報表導出工具類
 * 
 * @author JYLiu 
   @巴黎的雨季
    本工具是根據POI對Excel2003進行報表導出 本工具類可根據模板進行Excel的導出
 *     並且可根據提供的模板Sheet頁進行復制 從而實現多個Sheet頁的需求
 *     使用本工具類時,如果需求是每個Sheet頁中的數據都不一致,但是表格樣式和模板都一樣
 *     那么只需要在實際情況中根據 sql 來查詢要添加的數據源  (只需更改數據源即可)
 
 */
public class ExcelUtil {

    /**
     * 根據模板導出報表,可導出多個Sheet頁
     * 
     * @param 導出的Excel文件名
     * @param 模板路徑 (全路徑)
     * @param 數據源
     * @param 返回請求
     * @param 生成的Sheet頁的名稱集合
     * @param 數據源中Map集合的key值 (key值對應的value值順序要列名順序一致)
     * @param 開始 循環寫入數據 的行數(從第幾行開始寫入數據)
     */
    public static void ExcelByModel(String ExcelName, String ModelURl, List<Map<String, String>> dataSource, 
            HttpServletResponse response, String[] sheetNames, String[] keyNames, int rowNum) throws Exception {

        // 設置導出Excel報表的導出形式
        response.setContentType("application/vnd.ms-excel");
        // 設置導出Excel報表的響應文件名
        String fileName = new String(ExcelName.getBytes("utf-8"), "ISO-8859-1");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
        // 創建一個輸出流
        OutputStream fileOut = response.getOutputStream();
        // 讀取模板文件路徑
        File file = new File(ModelURl);
        FileInputStream fins = new FileInputStream(file);
        POIFSFileSystem fs = new POIFSFileSystem(fins);
        // 讀取Excel模板
        HSSFWorkbook wb = new HSSFWorkbook(fs);

        // 設置邊框樣式
        HSSFCellStyle style = wb.createCellStyle();
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 設置邊框樣式的顏色
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        style.setRightBorderColor(HSSFColor.BLACK.index);
        style.setTopBorderColor(HSSFColor.BLACK.index);

        // 模板頁
        HSSFSheet sheetModel = null;
        // 新建的Sheet頁
        HSSFSheet newSheet = null;
        // 創建行
        HSSFRow row = null;
        // 創建列
        HSSFCell cell = null;

        // 循環建立Sheet頁
        for (int i = 0; i < sheetNames.length; i++) {
            // 讀取模板中模板Sheet頁中的內容
            sheetModel = wb.getSheetAt(0);
            // 設置新建Sheet的頁名
            newSheet = wb.createSheet(sheetNames[i]);
            // 將模板中的內容復制到新建的Sheet頁中
            copySheet(wb, sheetModel, newSheet, sheetModel.getFirstRowNum(), sheetModel.getLastRowNum());
            
            //獲取到新建Sheet頁中的第一行為其中的列賦值
            row=newSheet.getRow(0);
            row.getCell(1).setCellValue("這是為表代碼賦的值");
            //注意 合並的單元格也要按照合並前的格數來算
            row.getCell(6).setCellValue("這是為外部代碼賦的值");
            
            //獲取模板中的第二列,並賦值
            row=newSheet.getRow(1);
            row.getCell(1).setCellValue("表名稱賦值");
            //注意 合並的單元格也要按照合並前的格數來算
            row.getCell(6).setCellValue("這是為是否系統表賦的值");
            
            // 遍歷數據源 開始寫入數據(因為Excel中是從0開始,所以減一)
            int num = rowNum - 1;
            for (Map<String, String> item : dataSource) {
                // 循環遍歷,新建行
                row = newSheet.createRow((short) num);
                //判斷有多少列數據
                for (int j = 0; j < keyNames.length; j++) {
                    // 設置每列的數據           設置每列的樣式            設置每列的值
                    cell = row.createCell(j); cell.setCellStyle(style); cell.setCellValue(item.get(keyNames[j]));
                }
                num++;
            }
            // break 加break可以測試只添加一個Sheet頁的情況
        }
        // 寫入流
        wb.write(fileOut);
        // 關閉流
        fileOut.close();
    }

    
    
    
    /**
     * 
     * @param Excel工作簿對象
     * @param 模板Sheet頁
     * @param 新建Sheet頁
     * @param 模板頁的第一行
     * @param 模板頁的最后一行
     */
    private static void copySheet(HSSFWorkbook wb, HSSFSheet fromsheet, HSSFSheet newSheet, int firstrow, int lasttrow) {

        // 復制一個單元格樣式到新建單元格
        if ((firstrow == -1) || (lasttrow == -1) || lasttrow < firstrow) {
            return;
        }
        // 復制合並的單元格
        Region region = null;
        for (int i = 0; i < fromsheet.getNumMergedRegions(); i++) {
            region = fromsheet.getMergedRegionAt(i);
            if ((region.getRowFrom() >= firstrow) && (region.getRowTo() <= lasttrow)) {
                newSheet.addMergedRegion(region);
            }
        }
        HSSFRow fromRow = null;
        HSSFRow newRow = null;
        HSSFCell newCell = null;
        HSSFCell fromCell = null;
        // 設置列寬
        for (int i = firstrow; i < lasttrow; i++) {
            fromRow = fromsheet.getRow(i);
            if (fromRow != null) {
                for (int j = fromRow.getLastCellNum(); j >= fromRow.getFirstCellNum(); j--) {
                    int colnum = fromsheet.getColumnWidth((short) j);
                    if (colnum > 100) {
                        newSheet.setColumnWidth((short) j, (short) colnum);
                    }
                    if (colnum == 0) {
                        newSheet.setColumnHidden((short) j, true);
                    } else {
                        newSheet.setColumnHidden((short) j, false);
                    }
                }
                break;
            }
        }

        // 復制行並填充數據
        for (int i = 0; i < lasttrow; i++) {
            fromRow = fromsheet.getRow(i);
            if (fromRow == null) {
                continue;
            }
            newRow = newSheet.createRow(i - firstrow);
            newRow.setHeight(fromRow.getHeight());
            for (int j = fromRow.getFirstCellNum(); j < fromRow.getPhysicalNumberOfCells(); j++) {
                fromCell = fromRow.getCell((short) j);
                if (fromCell == null) {
                    continue;
                }
                newCell = newRow.createCell((short) j);
                newCell.setCellStyle(fromCell.getCellStyle());
                int cType = fromCell.getCellType();
                newCell.setCellType(cType);
                switch (cType) {
                    case HSSFCell.CELL_TYPE_STRING:
                        newCell.setCellValue(fromCell.getRichStringCellValue());
                        break;
                    case HSSFCell.CELL_TYPE_NUMERIC:
                        newCell.setCellValue(fromCell.getNumericCellValue());
                        break;
                    case HSSFCell.CELL_TYPE_FORMULA:
                        newCell.setCellValue(fromCell.getCellFormula());
                        break;
                    case HSSFCell.CELL_TYPE_BOOLEAN:
                        newCell.setCellValue(fromCell.getBooleanCellValue());
                        break;
                    case HSSFCell.CELL_TYPE_ERROR:
                        newCell.setCellValue(fromCell.getErrorCellValue());
                        break;
                    default:
                        newCell.setCellValue(fromCell.getRichStringCellValue());
                        break;
                }
            }
        }
    }

}

 

以上便是整個工具類的核心代碼了

測試數據如下

/**
     * 測試多Sheet頁導出數據表格方法
     */
    public static void  ExcelTest(HttpServletResponse response){
        
        //構建數據源
        List<Map<String, String>> dataSourceList=new ArrayList<Map<String,String>>(){
            {
                add(new HashMap<String, String>(){{
                    put("字段編號", "1");
                    put("字段代碼", "BUSINESS_ID");
                    put("字段含義", "業務id");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", "");
                    put("主碼", "");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "2");
                    put("字段代碼", "PROC_INST_ID");
                    put("字段含義", "流程實例編號");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", "");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "3");
                    put("字段代碼", "PROC_STATE");
                    put("字段含義", "流程狀態");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "4");
                    put("字段代碼", "APPLICANT");
                    put("字段含義", "申請人");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "5");
                    put("字段代碼", "LEAVE_TYPE");
                    put("字段含義", "請假類型");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "6");
                    put("字段代碼", "REASON");
                    put("字段含義", "請假事因");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "7");
                    put("字段代碼", "BEGIN_TIME");
                    put("字段含義", "起始時間");
                    put("數據類型", "TIMESTAMP");
                    put("長度", "");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "8");
                    put("字段代碼", "END_TIME");
                    put("字段含義", "結束時間");
                    put("數據類型", "TIMESTAMP");
                    put("長度", "");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "9");
                    put("字段代碼", "INSERT_PERSON");
                    put("字段含義", "登記人");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
                add(new HashMap<String, String>(){{
                    put("字段編號", "10");
                    put("字段代碼", "APPROVEDBY");
                    put("字段含義", "批准人");
                    put("數據類型", "VARCHAR");
                    put("長度", "64");
                    put("主鍵", " ");
                    put("主碼", " ");
                }});
            }
        };
        //構建數據源中的key值
        String[] keysStrings={"字段編號","字段代碼","字段含義","數據類型","長度","主鍵","主碼"};
        //每頁的名稱
        String [] sheetNameStrings={"Sheet1","Sheet2","Sheet3","Sheet4","Sheet5","Sheet6"};
        String modelURLString="D:\\model\\model.xls";
        try {
            ExcelUtil.ExcelByModel("測試模板導出", modelURLString, dataSourceList, response, sheetNameStrings, keysStrings, 6);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

 

 

以上就是關於Excel報表根據模板導出並生成多個Sheet也的小工具了,需要的可以參考代碼,根據實際業務需求 進行代碼調整。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM