日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java poi 读取excel 编码_Java使用POI 读取和写入Excel指南

發布時間:2024/4/17 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java poi 读取excel 编码_Java使用POI 读取和写入Excel指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做項目時經常有通過程序讀取Excel數據,或是創建新的Excel并寫入數據的需求;網上很多經驗教程里使用的POI版本都比較老了,一些API在新版里已經廢棄,這里基于最新的Apache POI 4.0.1版本來總結一下整個讀取和寫入Excel的過程,希望能幫助到需要的人 ^_^

1. 準備工作

1.1 在項目中引入Apache POI相關類庫

引入?Apache POI?和?Apache POI-OOXML?這兩個類庫,Maven坐標如下:

org.apache.poi

poi

4.0.1

org.apache.poi

poi-ooxml

4.0.1

2. 讀取或寫入Excel數據

2.1 示例程序結構說明

簡單說明一下示例程序的整體結構:

ExcelReader.java是實現讀取Excel數據功能的類;

ExcelWriter.java是創建新的Excel并向其中寫入數據的類;

ExcelDataVO.java封裝了讀取或寫入時每一“行”的數據;

MainTest.java是示例程序的入口類,其中演示了讀取和寫入Excel數據的整個過程;

2.2 讀取數據

示例程序需要從桌面讀取 readExample.xlsx 內的數據,readExample.xlsx 的內容如下:

讀取Excel時主要調用ExcelReader.java類來讀取和解析Excel的具體內容,這里以讀取系統文件的形式演示讀取過程:(兼容 xls 和 xlsx)

2.2.1 主程序入口類代碼:

/**

* Author: Dreamer-1

* Date: 2019-03-01

* Time: 10:13

* Description: 示例程序入口類

*/

public class MainTest {

public static void main(String[] args) {

// 設定Excel文件所在路徑

String excelFileName = "/Users/Dreamer-1/Desktop/myBlog/java解析Excel/readExample.xlsx";

// 讀取Excel文件內容

List readResult = ExcelReader.readExcel(excelFileName);

// todo 進行業務操作

}

}

讀取和寫入時封裝每一“行”數據的ExcelDataVO.java代碼如下:

/**

* Author: Dreamer-1

* Date: 2019-03-01

* Time: 11:33

* Description: 讀取Excel時,封裝讀取的每一行的數據

*/

public class ExcelDataVO {

/**

* 姓名

*/

private String name;

/**

* 年齡

*/

private Integer age;

/**

* 居住地

*/

private String location;

/**

* 職業

*/

private String job;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getLocation() {

return location;

}

public void setLocation(String location) {

this.location = location;

}

public String getJob() {

return job;

}

public void setJob(String job) {

this.job = job;

}

}

2.2.2 Excel解析類的代碼:

/**

* Author: Dreamer-1

* Date: 2019-03-01

* Time: 10:21

* Description: 讀取Excel內容

*/

public class ExcelReader {

private static Logger logger = Logger.getLogger(ExcelReader.class.getName()); // 日志打印類

private static final String XLS = "xls";

private static final String XLSX = "xlsx";

/**

* 根據文件后綴名類型獲取對應的工作簿對象

* @param inputStream 讀取文件的輸入流

* @param fileType 文件后綴名類型(xls或xlsx)

* @return 包含文件數據的工作簿對象

* @throws IOException

*/

public static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {

Workbook workbook = null;

if (fileType.equalsIgnoreCase(XLS)) {

workbook = new HSSFWorkbook(inputStream);

} else if (fileType.equalsIgnoreCase(XLSX)) {

workbook = new XSSFWorkbook(inputStream);

}

return workbook;

}

/**

* 讀取Excel文件內容

* @param fileName 要讀取的Excel文件所在路徑

* @return 讀取結果列表,讀取失敗時返回null

*/

public static List readExcel(String fileName) {

Workbook workbook = null;

FileInputStream inputStream = null;

try {

// 獲取Excel后綴名

String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());

// 獲取Excel文件

File excelFile = new File(fileName);

if (!excelFile.exists()) {

logger.warning("指定的Excel文件不存在!");

return null;

}

// 獲取Excel工作簿

inputStream = new FileInputStream(excelFile);

workbook = getWorkbook(inputStream, fileType);

// 讀取excel中的數據

List resultDataList = parseExcel(workbook);

return resultDataList;

} catch (Exception e) {

logger.warning("解析Excel失敗,文件名:" + fileName + " 錯誤信息:" + e.getMessage());

return null;

} finally {

try {

if (null != workbook) {

workbook.close();

}

if (null != inputStream) {

inputStream.close();

}

} catch (Exception e) {

logger.warning("關閉數據流出錯!錯誤信息:" + e.getMessage());

return null;

}

}

}

/**

* 解析Excel數據

* @param workbook Excel工作簿對象

* @return 解析結果

*/

private static List parseExcel(Workbook workbook) {

List resultDataList = new ArrayList<>();

// 解析sheet

for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {

Sheet sheet = workbook.getSheetAt(sheetNum);

// 校驗sheet是否合法

if (sheet == null) {

continue;

}

// 獲取第一行數據

int firstRowNum = sheet.getFirstRowNum();

Row firstRow = sheet.getRow(firstRowNum);

if (null == firstRow) {

logger.warning("解析Excel失敗,在第一行沒有讀取到任何數據!");

}

// 解析每一行的數據,構造數據對象

int rowStart = firstRowNum + 1;

int rowEnd = sheet.getPhysicalNumberOfRows();

for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {

Row row = sheet.getRow(rowNum);

if (null == row) {

continue;

}

ExcelDataVO resultData = convertRowToData(row);

if (null == resultData) {

logger.warning("第 " + row.getRowNum() + "行數據不合法,已忽略!");

continue;

}

resultDataList.add(resultData);

}

}

return resultDataList;

}

/**

* 將單元格內容轉換為字符串

* @param cell

* @return

*/

private static String convertCellValueToString(Cell cell) {

if(cell==null){

return null;

}

String returnValue = null;

switch (cell.getCellType()) {

case NUMERIC: //數字

Double doubleValue = cell.getNumericCellValue();

// 格式化科學計數法,取一位整數

DecimalFormat df = new DecimalFormat("0");

returnValue = df.format(doubleValue);

break;

case STRING: //字符串

returnValue = cell.getStringCellValue();

break;

case BOOLEAN: //布爾

Boolean booleanValue = cell.getBooleanCellValue();

returnValue = booleanValue.toString();

break;

case BLANK: // 空值

break;

case FORMULA: // 公式

returnValue = cell.getCellFormula();

break;

case ERROR: // 故障

break;

default:

break;

}

return returnValue;

}

/**

* 提取每一行中需要的數據,構造成為一個結果數據對象

*

* 當該行中有單元格的數據為空或不合法時,忽略該行的數據

*

* @param row 行數據

* @return 解析后的行數據對象,行數據錯誤時返回null

*/

private static ExcelDataVO convertRowToData(Row row) {

ExcelDataVO resultData = new ExcelDataVO();

Cell cell;

int cellNum = 0;

// 獲取姓名

cell = row.getCell(cellNum++);

String name = convertCellValueToString(cell);

resultData.setName(name);

// 獲取年齡

cell = row.getCell(cellNum++);

String ageStr = convertCellValueToString(cell);

if (null == ageStr || "".equals(ageStr)) {

// 年齡為空

resultData.setAge(null);

} else {

resultData.setAge(Integer.parseInt(ageStr));

}

// 獲取居住地

cell = row.getCell(cellNum++);

String location = convertCellValueToString(cell);

resultData.setLocation(location);

// 獲取職業

cell = row.getCell(cellNum++);

String job = convertCellValueToString(cell);

resultData.setJob(job);

return resultData;

}

}

2.2.3 應用場景補充

一般我們會有這樣的應用場景,即:在前臺頁面的文件上傳入口上傳本地的Excel文件到后臺,后臺收到Excel文件后進行解析并做對應的業務操作;這里假設前臺已經有了上傳文件的入口,再簡單貼一下后臺的解析代碼;

后臺接收前臺數據的Controller層代碼示例:

@PostMapping("/uploadExcel")

public ResponseEntity> uploadImage(MultipartFile file) {

// 檢查前臺數據合法性

if (null == file || file.isEmpty()) {

logger.warning("上傳的Excel商品數據文件為空!上傳時間:" + new Date());

return new ResponseEntity<>(HttpStatus.BAD_REQUEST);

}

try {

// 解析Excel

List parsedResult = ExcelReader.readExcel(file);

// todo 進行業務操作

return new ResponseEntity<>(HttpStatus.OK);

} catch (Exception e) {

logger.warning("上傳的Excel商品數據文件為空!上傳時間:" + new Date());

return new ResponseEntity<>(HttpStatus.BAD_REQUEST);

}

}

ExcelReader.java中的?readExcel()?方法需要做一定的修改,代碼如下:

/**

* 讀取Excel文件內容

* @param file 上傳的Excel文件

* @return 讀取結果列表,讀取失敗時返回null

*/

public static List readExcel(MultipartFile file) {

Workbook workbook = null;

try {

// 獲取Excel后綴名

String fileName = file.getOriginalFilename();

if (fileName == null || fileName.isEmpty() || fileName.lastIndexOf(".") < 0) {

logger.warning("解析Excel失敗,因為獲取到的Excel文件名非法!");

return null;

}

String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());

// 獲取Excel工作簿

workbook = getWorkbook(file.getInputStream(), fileType);

// 讀取excel中的數據

List resultDataList = parseExcel(workbook);

return resultDataList;

} catch (Exception e) {

logger.warning("解析Excel失敗,文件名:" + file.getOriginalFilename() + " 錯誤信息:" + e.getMessage());

return null;

} finally {

try {

if (null != workbook) {

workbook.close();

}

} catch (Exception e) {

logger.warning("關閉數據流出錯!錯誤信息:" + e.getMessage());

return null;

}

}

}

2.3 寫入數據

寫入數據時主要調用ExcelWriter.java來創建Excel工作簿對象并寫入數據,這里以寫入系統文件數據為例演示寫入的過程:

2.3.1 主程序入口類代碼

/**

* Author: Dreamer-1

* Date: 2019-03-01

* Time: 10:13

* Description: 示例程序入口類

*/

public class MainTest {

private static Logger logger = Logger.getLogger(MainTest.class.getName());

public static void main(String[] args) {

// 創建需要寫入的數據列表

List dataVOList = new ArrayList<>(2);

ExcelDataVO dataVO = new ExcelDataVO();

dataVO.setName("小明");

dataVO.setAge(18);

dataVO.setLocation("廣州");

dataVO.setJob("大學生");

ExcelDataVO dataVO2 = new ExcelDataVO();

dataVO2.setName("小花");

dataVO2.setAge(19);

dataVO2.setLocation("深圳");

dataVO2.setJob("大學生");

dataVOList.add(dataVO);

dataVOList.add(dataVO2);

// 寫入數據到工作簿對象內

Workbook workbook = ExcelWriter.exportData(dataVOList);

// 以文件的形式輸出工作簿對象

FileOutputStream fileOut = null;

try {

String exportFilePath = "/Users/Dreamer-1/Desktop/myBlog/java解析Excel/writeExample.xlsx";

File exportFile = new File(exportFilePath);

if (!exportFile.exists()) {

exportFile.createNewFile();

}

fileOut = new FileOutputStream(exportFilePath);

workbook.write(fileOut);

fileOut.flush();

} catch (Exception e) {

logger.warning("輸出Excel時發生錯誤,錯誤原因:" + e.getMessage());

} finally {

try {

if (null != fileOut) {

fileOut.close();

}

if (null != workbook) {

workbook.close();

}

} catch (IOException e) {

logger.warning("關閉輸出流時發生錯誤,錯誤原因:" + e.getMessage());

}

}

}

}

2.3.2 寫入Excel類的代碼

ExcelWriter.java類中,你可以根據實際需要替換?CELL_HEADS?列頭的信息,然后重寫?convertDataToRow?方法,轉換你自己的行數據;

/**

* Author: Dreamer-1

* Date: 2019-03-01

* Time: 11:09

* Description: 生成Excel并寫入數據

*/

public class ExcelWriter {

private static List CELL_HEADS; //列頭

static{

// 類裝載時就載入指定好的列頭信息,如有需要,可以考慮做成動態生成的列頭

CELL_HEADS = new ArrayList<>();

CELL_HEADS.add("姓名");

CELL_HEADS.add("年齡");

CELL_HEADS.add("居住城市");

CELL_HEADS.add("職業");

}

/**

* 生成Excel并寫入數據信息

* @param dataList 數據列表

* @return 寫入數據后的工作簿對象

*/

public static Workbook exportData(List dataList){

// 生成xlsx的Excel

Workbook workbook = new SXSSFWorkbook();

// 如需生成xls的Excel,請使用下面的工作簿對象,注意后續輸出時文件后綴名也需更改為xls

//Workbook workbook = new HSSFWorkbook();

// 生成Sheet表,寫入第一行的列頭

Sheet sheet = buildDataSheet(workbook);

//構建每行的數據內容

int rowNum = 1;

for (Iterator it = dataList.iterator(); it.hasNext(); ) {

ExcelDataVO data = it.next();

if (data == null) {

continue;

}

//輸出行數據

Row row = sheet.createRow(rowNum++);

convertDataToRow(data, row);

}

return workbook;

}

/**

* 生成sheet表,并寫入第一行數據(列頭)

* @param workbook 工作簿對象

* @return 已經寫入列頭的Sheet

*/

private static Sheet buildDataSheet(Workbook workbook) {

Sheet sheet = workbook.createSheet();

// 設置列頭寬度

for (int i=0; i

sheet.setColumnWidth(i, 4000);

}

// 設置默認行高

sheet.setDefaultRowHeight((short) 400);

// 構建頭單元格樣式

CellStyle cellStyle = buildHeadCellStyle(sheet.getWorkbook());

// 寫入第一行各列的數據

Row head = sheet.createRow(0);

for (int i = 0; i < CELL_HEADS.size(); i++) {

Cell cell = head.createCell(i);

cell.setCellValue(CELL_HEADS.get(i));

cell.setCellStyle(cellStyle);

}

return sheet;

}

/**

* 設置第一行列頭的樣式

* @param workbook 工作簿對象

* @return 單元格樣式對象

*/

private static CellStyle buildHeadCellStyle(Workbook workbook) {

CellStyle style = workbook.createCellStyle();

//對齊方式設置

style.setAlignment(HorizontalAlignment.CENTER);

//邊框顏色和寬度設置

style.setBorderBottom(BorderStyle.THIN);

style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); // 下邊框

style.setBorderLeft(BorderStyle.THIN);

style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); // 左邊框

style.setBorderRight(BorderStyle.THIN);

style.setRightBorderColor(IndexedColors.BLACK.getIndex()); // 右邊框

style.setBorderTop(BorderStyle.THIN);

style.setTopBorderColor(IndexedColors.BLACK.getIndex()); // 上邊框

//設置背景顏色

style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

//粗體字設置

Font font = workbook.createFont();

font.setBold(true);

style.setFont(font);

return style;

}

/**

* 將數據轉換成行

* @param data 源數據

* @param row 行對象

* @return

*/

private static void convertDataToRow(ExcelDataVO data, Row row){

int cellNum = 0;

Cell cell;

// 姓名

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getName() ? "" : data.getName());

// 年齡

cell = row.createCell(cellNum++);

if (null != data.getAge()) {

cell.setCellValue(data.getAge());

} else {

cell.setCellValue("");

}

// 所在城市

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getLocation() ? "" : data.getLocation());

// 職業

cell = row.createCell(cellNum++);

cell.setCellValue(null == data.getJob() ? "" : data.getJob());

}

}

示例程序運行后將會在指定的系統路徑下生成?writeExample.xlsx文件,其內容如下:

2.3.3 應用場景補充

一般寫入Excel時會有這樣的場景:前臺頁面上有一個導出按鈕,點擊后將后臺某張表里的數據以Excel的形式導出,導出的Excel文件通過瀏覽器下載到用戶系統中;這里默認前臺頁面已經有相應的按鈕功能,給出對應的Controller層代碼供參考:

@GetMapping("/exportExcel")

public void exportExcel(HttpServletRequest request, HttpServletResponse response) {

Workbook workbook = null;

OutputStream out = null;

try {

// todo 根據業務需求獲取需要寫入Excel的數據列表 dataList

// 生成Excel工作簿對象并寫入數據

workbook = ExcelWriter.exportData(dataList);

// 寫入Excel文件到前端

if(null != workbook){

String excelName = "示例Excel導出";

String fileName = excelName + DateUtil.format(new Date(), DateUtil.SHORT_DATE) + ".xlsx";

fileName = new String(fileName.getBytes("UTF-8"),"iso8859-1");

response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

response.setContentType("application/x-download");

response.setCharacterEncoding("UTF-8");

response.addHeader("Pargam", "no-cache");

response.addHeader("Cache-Control", "no-cache");

response.flushBuffer();

out = response.getOutputStream();

workbook.write(out);

out.flush();

}

} catch (Exception e) {

logger.WARNING("寫入Excel過程出錯!錯誤原因:" + e.getMessage());

} finally {

try {

if (null != workbook) {

workbook.close();

}

if (null != out) {

out.close();

}

} catch (IOException e) {

logger.WARNING("關閉workbook或outputStream出錯!");

}

}

}

// 前臺頁面發送請求到后臺Controller時的JS代碼可參考:

var url = "/exportExcel";

window.location=url;

3. 源碼下載

原文來自:https://www.cnblogs.com/Dreamer-1/p/10469430.html

總結

以上是生活随笔為你收集整理的java poi 读取excel 编码_Java使用POI 读取和写入Excel指南的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。