91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Java中使用POI讀取和寫入Excel

發布時間:2021-06-08 17:26:03 來源:億速云 閱讀:444 作者:Leah 欄目:編程語言

今天就跟大家聊聊有關如何在Java中使用POI讀取和寫入Excel,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

1. 準備工作

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

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

 <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>

2. 讀取或寫入Excel數據

2.1 示例程序結構說明

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

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

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

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

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

2.2 讀取數據

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

如何在Java中使用POI讀取和寫入Excel

讀取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<ExcelDataVO> 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<ExcelDataVO> 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<ExcelDataVO> 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<ExcelDataVO> parseExcel(Workbook workbook) {
 List<ExcelDataVO> 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<ExcelDataVO> 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<ExcelDataVO> 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<ExcelDataVO> 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<ExcelDataVO> 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<String> 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<ExcelDataVO> dataList){
  // 生成xlsx的Excel
  Workbook workbook = new SXSSFWorkbook();

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

  // 生成Sheet表,寫入第一行的列頭
  Sheet sheet = buildDataSheet(workbook);
  //構建每行的數據內容
  int rowNum = 1;
  for (Iterator<ExcelDataVO> 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<CELL_HEADS.size(); 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文件,其內容如下:

如何在Java中使用POI讀取和寫入Excel

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;

看完上述內容,你們對如何在Java中使用POI讀取和寫入Excel有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

连城县| 托克托县| 东明县| 凤山市| 盈江县| 屏山县| 威远县| 汝州市| 吉木乃县| 万源市| 高州市| 大同县| 平顶山市| 阜平县| 聊城市| 凤翔县| 宣化县| 绩溪县| 安福县| 醴陵市| 荥经县| 龙里县| 罗甸县| 涟源市| 元谋县| 隆安县| 东乡县| 克山县| 来安县| 东平县| 新民市| 久治县| 息烽县| 乐平市| 镇安县| 鄂托克前旗| 福泉市| 南陵县| 崇州市| 定西市| 萍乡市|