POI實現Excel匯入匯出(轉)
阿新 • • 發佈:2018-12-22
利用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);
}
}