1. 程式人生 > >POI實現Excel匯入匯出(轉)

POI實現Excel匯入匯出(轉)

利用idea建立java web的maven專案,在pom中新增對poi的jar的依賴。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hand</groupId>
  <artifactId>excel-data</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>excel-data Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.14</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>excel-data</finalName>
  </build>
</project>

web.xml中配置下後續匯出時,所需要的servlet對映資訊:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>TestServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
  </servlet-mapping>
</web-app>

Excel匯入工具類實現:

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 
[email protected]
* @version 1.0 * @name * @description 讀取並解析excel * @date 2017/10/19 */ public class ImportExcel { private POIFSFileSystem fs; private HSSFWorkbook wb; private HSSFSheet sheet; private HSSFRow row; /** * 讀取Excel表格表頭的內容 * @param is * @return String 表頭內容的陣列 */ public String[] readExcelTitle(InputStream is) { try { fs = new POIFSFileSystem(is); wb = new HSSFWorkbook(fs); } catch (IOException e) { e.printStackTrace(); } sheet = wb.getSheetAt(0); //得到首行的row row = sheet.getRow(0); // 標題總列數 int colNum = row.getPhysicalNumberOfCells(); String[] title = new String[colNum]; for (int i = 0; i < colNum; i++) { title[i] = getCellFormatValue(row.getCell((short) i)); } return title; } /** * 讀取Excel資料內容 * @param is * @return Map 包含單元格資料內容的Map物件 */ public Map<Integer, String> readExcelContent(InputStream is) { Map<Integer, String> content = new HashMap<Integer, String>(); String str = ""; try { fs = new POIFSFileSystem(is); wb = new HSSFWorkbook(fs); } catch (IOException e) { e.printStackTrace(); } sheet = wb.getSheetAt(0); // 得到總行數 int rowNum = sheet.getLastRowNum(); //由於第0行和第一行已經合併了 在這裡索引從2開始 row = sheet.getRow(2); int colNum = row.getPhysicalNumberOfCells(); // 正文內容應該從第二行開始,第一行為表頭的標題 for (int i = 2; i <= rowNum; i++) { row = sheet.getRow(i); int j = 0; while (j < colNum) { str += getCellFormatValue(row.getCell((short) j)).trim() + "-"; j++; } content.put(i, str); str = ""; } return content; } /** * 獲取單元格資料內容為字串型別的資料 * * @param cell Excel單元格 * @return String 單元格資料內容 */ private String getStringCellValue(HSSFCell cell) { String strCell = ""; switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_STRING: strCell = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_NUMERIC: strCell = String.valueOf(cell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_BOOLEAN: strCell = String.valueOf(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_BLANK: strCell = ""; break; default: strCell = ""; break; } if (strCell.equals("") || strCell == null) { return ""; } if (cell == null) { return ""; } return strCell; } /** * 獲取單元格資料內容為日期型別的資料 * * @param cell * Excel單元格 * @return String 單元格資料內容 */ private String getDateCellValue(HSSFCell cell) { String result = ""; try { int cellType = cell.getCellType(); if (cellType == HSSFCell.CELL_TYPE_NUMERIC) { Date date = cell.getDateCellValue(); result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1) + "-" + date.getDate(); } else if (cellType == HSSFCell.CELL_TYPE_STRING) { String date = getStringCellValue(cell); result = date.replaceAll("[年月]", "-").replace("日", "").trim(); } else if (cellType == HSSFCell.CELL_TYPE_BLANK) { result = ""; } } catch (Exception e) { System.out.println("日期格式不正確!"); e.printStackTrace(); } return result; } /** * 根據HSSFCell型別設定資料 * @param cell * @return */ private String getCellFormatValue(HSSFCell cell) { String cellvalue = ""; if (cell != null) { // 判斷當前Cell的Type switch (cell.getCellType()) { // 如果當前Cell的Type為NUMERIC case HSSFCell.CELL_TYPE_NUMERIC: case HSSFCell.CELL_TYPE_FORMULA: { // 判斷當前的cell是否為Date if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); cellvalue = sdf.format(date); } // 如果是純數字 else { // 取得當前Cell的數值 cellvalue = String.valueOf(cell.getNumericCellValue()); } break; } // 如果當前Cell的Type為STRIN case HSSFCell.CELL_TYPE_STRING: // 取得當前的Cell字串 cellvalue = cell.getRichStringCellValue().getString(); break; // 預設的Cell值 default: cellvalue = " "; } } else { cellvalue = ""; } return cellvalue; } public static void main(String[] args) { try { // 對讀取Excel表格標題測試 InputStream is = new FileInputStream("d:\\test2.xls"); ImportExcel excelReader = new ImportExcel(); String[] title = excelReader.readExcelTitle(is); System.out.println("獲得Excel表格的標題:"); for (String s : title) { System.out.print(s + " "); } System.out.println(); // 對讀取Excel表格內容測試 InputStream is2 = new FileInputStream("d:\\test2.xls"); Map<Integer, String> map = excelReader.readExcelContent(is2); System.out.println("獲得Excel表格的內容:"); //這裡由於xls合併了單元格需要對索引特殊處理 for (int i = 2; i <= map.size()+1; i++) { System.out.println(map.get(i)); } } catch (FileNotFoundException e) { System.out.println("未找到指定路徑的檔案!"); e.printStackTrace(); } } }

在這裡插入圖片描述
在這裡插入圖片描述
將Excel中的資料通過後臺程式維護到一個Map集合中,再利用String的split方法以“-”進行分割,得到單個的值,如果想要將這批資料插入到資料庫,則去例項化物件的dto,再給dto對應屬性賦值,最終寫sql再insert到表中。

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddress;
  6 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @name
 * @description
 * @date 2017/10/19
 */
public class ExportExcel {

    /**
     * 顯示的匯出表的標題
     */
    private String title;

    /**
     * 匯出表的列名
     */
    private String[] columnName;

    /**
     * 需要匯出的資料集合
     */
    private List<Object[]> dataList = new ArrayList<Object[]>();

    /**
     * 輸入流物件
     */
    private HttpServletRequest request;

    /**
     * 輸出流物件
     */
    private HttpServletResponse response;


    /**
     *
     * @param title
     * @param columnName
     * @param dataList
     * @param request
     * @param response
     * @description 構造方法,傳入要匯出的資料
     */
    public ExportExcel(String title, String[] columnName, List<Object[]> dataList,HttpServletRequest request,HttpServletResponse response) {
        this.dataList = dataList;
        this.columnName = columnName;
        this.title = title;
        this.request = request;
        this.response= response;
    }


    /**
     * @param
     * @return
     * @author [email protected]
     * @date 2017/10/19 13:21
     * @description 匯出資料到excel
     */
    public void export() throws Exception {

        try {
            HSSFWorkbook workbook = new HSSFWorkbook();                        // 建立工作簿物件
            HSSFSheet sheet = workbook.createSheet(title);                     // 建立工作表

            // 產生表格標題行
            HSSFRow rowm = sheet.createRow(0);
            HSSFCell cellTiltle = rowm.createCell(0);

            //設定標題和單元格樣式
            HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);  //獲取列頭樣式物件
            HSSFCellStyle style = this.getStyle(workbook);                    //單元格樣式物件

            //合併單元格
            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (columnName.length - 1)));
            cellTiltle.setCellStyle(columnTopStyle);
            cellTiltle.setCellValue(title);

            // 定義所需列數
            int columnNum = columnName.length;
            HSSFRow rowRowName = sheet.createRow(2);                 // 在索引2的位置建立行(最頂端的行開始的第二行)


            // 將列頭設定到sheet的單元格中
            for (int n = 0; n < columnNum; n++) {
                HSSFCell cellRowName = rowRowName.createCell(n);                  //建立列頭對應個數的單元格
                cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);                //設定列頭單元格的資料型別
                HSSFRichTextString text = new HSSFRichTextString(columnName[n]);
                cellRowName.setCellValue(text);                                    //設定列頭單元格的值
                cellRowName.setCellStyle(columnTopStyle);                          //設定列頭單元格樣式
            }

            //將查詢出的資料設定到sheet對應的單元格中
            for (int i = 0; i < dataList.size(); i++) {
                Object[] obj = dataList.get(i);//遍歷每個物件
                HSSFRow row = sheet.createRow(i + 3);//建立所需的行數
                for (int j = 0; j < obj.length; j++) {
                    HSSFCell cell = null;   //設定單元格的資料型別
                    //第一列為數字型別並設定單元格的值
                    if (j == 0) {
                        cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC);
                        cell.setCellValue(i + 1);
                    } else {
                        //其他列為字串型別並設定單元格的值
                        cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING);
                        if (!"".equals(obj[j]) && obj[j] != null) {
                            cell.setCellValue(obj[j].toString());
                        }
                    }
                    cell.setCellStyle(style);                                    //設定單元格樣式
                }
            }


            //讓列寬隨著匯出的列長自動適應
            for (int colNum = 0; colNum < columnNum; colNum++) {
                int columnWidth = sheet.getColumnWidth(colNum) / 256;
                for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
                    HSSFRow currentRow;
                    //當前行未被使用過
                    if (sheet.getRow(rowNum) == null) {
                        currentRow = sheet.createRow(rowNum);
                    } else {
                        currentRow = sheet.getRow(rowNum);
                    }
                    if (currentRow.getCell(colNum) != null) {
                        //取得當前的單元格
                        HSSFCell currentCell = currentRow.getCell(colNum);
                        //如果當前單元格型別為字串
                        if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                            int length = currentCell.getStringCellValue().getBytes().length;
                            if (columnWidth < length) {
                                //將單元格里面值大小作為列寬度
                                columnWidth = length;
                            }
                        }
                    }
                }
                //再根據不同列單獨做下處理
                if (colNum == 0) {
                    sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
                } else {
                    sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
                }
            }

            if (workbook != null) {
                try {
                    String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls";
                    String headStr = "attachment; filename=\"" + fileName + "\"";
                    response.setContentType("APPLICATION/OCTET-STREAM");
                    response.setHeader("Content-Disposition", headStr);
                    OutputStream out1 = response.getOutputStream();
                    workbook.write(out1);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * @param
     * @return
     * @author [email protected]
     * @date 2017/10/19 13:31
     * @description 標題行的單元格樣式
     */
    public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {

        // 設定字型
        HSSFFont font = workbook.createFont();
        //設定字型大小
        font.setFontHeightInPoints((short) 11);
        //字型加粗
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //設定字型名字
        font.setFontName("Courier New");
        //設定樣式;
        HSSFCellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.BLUE.getIndex());
        //設定底邊框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //設定底邊框顏色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //設定左邊框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //設定左邊框顏色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //設定右邊框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //設定右邊框顏色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //設定頂邊框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //設定頂邊框顏色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在樣式用應用設定的字型;
        style.setFont(font);
        //設定自動換行;
        style.setWrapText(false);
        //設定水平對齊的樣式為居中對齊;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //設定垂直對齊的樣式為居中對齊;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;
    }

    /**
     * @param
     * @return
     * @author [email protected]
     * @date 2017/10/19 13:31
     * @description 列資料資訊單元格樣式
     */
    public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
        // 設定字型
        HSSFFont font = workbook.createFont();
        //設定字型大小
        //font.setFontHeightInPoints((short)10);
        //字型加粗
        //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        //設定字型名字
        font.setFontName("Courier New");
        //設定樣式;
        HSSFCellStyle style = workbook.createCellStyle();
        //設定底邊框;
        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        //設定底邊框顏色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //設定左邊框;
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        //設定左邊框顏色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //設定右邊框;
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
        //設定右邊框顏色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //設定頂邊框;
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
        //設定頂邊框顏色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在樣式用應用設定的字型;
        style.setFont(font);
        //設定自動換行;
        style.setWrapText(false);
        //設定水平對齊的樣式為居中對齊;
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        //設定垂直對齊的樣式為居中對齊;
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        return style;
    }
}

用於測試匯出的Servlet程式:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @name
 * @description
 * @date 2017/10/19
 */
@WebServlet(name = "TestServlet")
public class TestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String title = "貨運單據匯出";
        String[] columnName = new String[]{"序號","num1","num2"};
        List<Object[]> dataList = new ArrayList<Object[]>();
        Object[] objs;
        for (int i = 0; i <2; i++) {
            objs = new Object[columnName.length];
            objs[0] = i;
            objs[1] = "1";
            objs[2] = "2";
            dataList.add(objs);
        }
        //例項化工具類
        ExportExcel ex = new ExportExcel(title, columnName, dataList,request,response);
        try {
            //匯出excel
            ex.export();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

在這裡插入圖片描述