【POI框架實戰】——POI匯出Excel時設定單元格型別為數值型別
背 景
最近做的一個ITFIN的專案中,後臺需要用POI實現匯出功能,匯出的資料中有文字格式,也有貨幣格式,所以為了方便在將來匯出的表格中做計算,存放貨幣的單元格需要設定為數值型別。
匯出的Excel的單元格都是文字格式(單元格左上角有個小三角):
費了不少功夫,終於把“小三角”去掉了,這裡總結並分享一下問題的解決方法。
通過poi匯出excel的過程大致是這樣的:
規定單元格的格式
↓
建立單元格
↓
設定單元格的格式
↓
設定資料的格式
↓
把資料存放到單元格中
↓
通過IO流輸出
背景POI匯出Excel時設定單元格型別為數值型別
要想存放數值的單元格以數值型別匯出,其中最關鍵的步驟就是上面加粗的兩步,設定單元格的格式和向單元格中存放資料。
核心程式碼如下:
/**
* 匯出Excel-胡玉洋-2015年11月11日
*
*@param outPutParam Excel資料實體,包括要匯出的excel標頭、列標題、資料等
* */
private void createContentRows(ExcelParam outPutParam) {
HSSFWorkbook workbook=new HSSFWorkbook(); //建立一個Excel檔案
// 遍歷集合資料,產生資料行
for (int i = 0; i < outPutParam.getContent().size(); i++) {
int rowIndex = i + 2;
HSSFRow contentRow = sheet.createRow(rowIndex);
Map<String, Object> rowDate = outPutParam.getContent().get(i);
//遍歷列
for (int j = 0; j < outPutParam.getTitleList().size(); j++) {
Title headTitle = outPutParam.getTitleList().get(j);//獲取第i行第j列列標題
String headerName = headTitle.getName();//獲取第j列列標識
Object data = rowDate.get(headerName);//獲取第i行第j列所放資料
HSSFCellStyle contextstyle =workbook.createCellStyle();
HSSFCell contentCell = contentRow.createCell(j);
Boolean isNum = false;//data是否為數值型
Boolean isInteger=false;//data是否為整數
Boolean isPercent=false;//data是否為百分數
if (data != null || "".equals(data)) {
//判斷data是否為數值型
isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");
//判斷data是否為整數(小數部分是否為0)
isInteger=data.toString().matches("^[-\\+]?[\\d]*$");
//判斷data是否為百分數(是否包含“%”)
isPercent=data.toString().contains("%");
}
//如果單元格內容是數值型別,涉及到金錢(金額、本、利),則設定cell的型別為數值型,設定data的型別為數值型別
if (isNum && !isPercent) {
HSSFDataFormat df = workbook.createDataFormat(); // 此處設定資料格式
if (isInteger) {
contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//資料格式只顯示整數
}else{
contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留兩位小數點
}
// 設定單元格格式
contentCell.setCellStyle(contextstyle);
// 設定單元格內容為double型別
contentCell.setCellValue(Double.parseDouble(data.toString()));
} else {
contentCell.setCellStyle(contextstyle);
// 設定單元格內容為字元型
contentCell.setCellValue(data.toString());
}
}
}
}
如上,有兩個比較重要的點:
1、先用正則表示式判斷資料是否為數值型,如果為數值型,則設定單元格格式為整數或者小數;
2、然後往單元格中存放資料的時候要設定資料的格式為double型別,如果檢視poi的原始碼HSSFCell.java會發現設定資料的方法如下,所以用setCellValue(double)方法即可。
優化
到了這裡,您可能以為萬事大吉啊了,其實上面的程式碼有個陷阱,如果不經過大資料量的測試是發覺不出來的哦~~
如果資料量大的話,系統可能會報錯“The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook”,原因是style建立的次數太多了,解決這個問題的方法很簡單,在迴圈體外面建立單元格格式contextstyle(即把它當成一個“全域性”變數),不要在迴圈內部建立。
正確的程式碼如下:
/**
* 匯出Excel-胡玉洋-2015年11月11日
*
*@param outPutParam Excel資料實體,包括要匯出的excel標頭、列標題、資料等
* */
private void createContentRows(ExcelParam outPutParam) {
HSSFWorkbook workbook=new HSSFWorkbook(); //建立一個Excel檔案
HSSFCellStyle contextstyle =workbook.createCellStyle();
// 遍歷集合資料,產生資料行
for (int i = 0; i < outPutParam.getContent().size(); i++) {
int rowIndex = i + 2;
HSSFRow contentRow = sheet.createRow(rowIndex);
Map<String, Object> rowDate = outPutParam.getContent().get(i);
//遍歷列
for (int j = 0; j < outPutParam.getTitleList().size(); j++) {
Title headTitle = outPutParam.getTitleList().get(j);//獲取第i行第j列列標題
String headerName = headTitle.getName();//獲取第j列列標識
Object data = rowDate.get(headerName);//獲取第i行第j列所放資料
HSSFCell contentCell = contentRow.createCell(j);
Boolean isNum = false;//data是否為數值型
Boolean isInteger=false;//data是否為整數
Boolean isPercent=false;//data是否為百分數
if (data != null || "".equals(data)) {
//判斷data是否為數值型
isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");
//判斷data是否為整數(小數部分是否為0)
isInteger=data.toString().matches("^[-\\+]?[\\d]*$");
//判斷data是否為百分數(是否包含“%”)
isPercent=data.toString().contains("%");
}
//如果單元格內容是數值型別,涉及到金錢(金額、本、利),則設定cell的型別為數值型,設定data的型別為數值型別
if (isNum && !isPercent) {
HSSFDataFormat df = workbook.createDataFormat(); // 此處設定資料格式
if (isInteger) {
contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//資料格式只顯示整數
}else{
contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留兩位小數點
}
// 設定單元格格式
contentCell.setCellStyle(contextstyle);
// 設定單元格內容為double型別
contentCell.setCellValue(Double.parseDouble(data.toString()));
} else {
contentCell.setCellStyle(contextstyle);
// 設定單元格內容為字元型
contentCell.setCellValue(data.toString());
}
}
}
}
最後匯出的正確格式:
相關推薦
【POI框架實戰】——POI匯出Excel時設定單元格型別為數值型別
背 景 最近做的一個ITFIN的專案中,後臺需要用POI實現匯出功能,匯出的資料中有文字格式,也有貨幣格式,所以為了方便在將來匯出的表格中做計算,存放貨幣的單元格需要設定為數值型別。 匯出的Excel的單元格都是文字格式(單元格左上角有個小三
laravel匯出excel並設定單元格格式
$list = $this->recommend($request); $data = array(); foreach($list as $k=>$v){ $data[] = array_values($v); $len = count($v); } $header =
C# DataGridView匯出Excel,設定單元格合併,隱藏行
不得不承認,做程式需要研究。 DataGridView匯出Excel的原始碼 using System.Windows.Forms;using System.Collections.Generic;using System;using Microsoft.Office.In
poi匯出Excel時設定某個單元格顏色
需求: 查詢資料庫表資料然後到另一個表找錯誤的對應欄位(就是找到需要填充的單元格所在行的列),對這個單元格進行設定背景色,然後匯出資料。 具體的工具類如下 import cn.afterturn.easypoi.excel.annotatio
POI 匯出Excel實現合併單元格以及列自適應寬度
目錄 參考推薦: POI 匯出Excel 1. 合併單元格 POI是apache提供的一個讀寫Excel文件的開源元件,在操作excel時常要合併單元格,合併單元格的方法是: public CellRang
apache POI匯出excel檔案 及單元格合併 、樣式的設定
客戶需要從完單物料資訊中到處excel 大概思路: 單擊某一按鈕,觸發請求至後臺,建立輸出流,匯出excel ^_^ 前臺程式碼: (此段程式碼 註釋部分存在一個問題,註釋部分的請求無效,後臺無法響應前臺請求, 引數傳過去了,後臺也接受了,但輸出流沒有輸出,木雞wh
java poi 匯入excel時 讀取單元格內容的方法 ,其中包含excel中有函式的讀法
public static String getExcelCellValue(Cell cell) { String ret = ""; try { if (cell == null) { ret = ""; } else if (cell.get
C#實戰016:Excel操作-設定單元格屬性
獲取單元格之後我們需要對單元格進行操作,比如過單元格寬、單元格高、單元格背景色、單元格邊框等等。 App = new Application(); //建立 Excel物件 object missing = Missing.Value; //獲取缺少
【ios學習記錄】-如何定製UITableView的圓角單元格
自從ios7更新以來,UITableView控制元件的邊角style由預設圓角變成了直角,更加適應UI扁平化設計的效果了。但對於某種情況來說,如果tableview寬度不是拉伸到與父檢視等寬,那麼使用直角的tableview則會顯得不好看。如下圖分組列
jxl匯出excel(合併單元格)
Demo import java.io.*; import jxl.*; import jxl.format.UnderlineStyle; import jxl.write.*; publicclass CreateXLS { public
C#匯出Excel,某單元格內容長度超過255 的解決方法
只需要將該列首個單元格指定為memo型別就可以了! C# code publicstaticvoid ToExcel(DataTable dtSource, string strPath, string strSheetName) { System.Data.OleD
解決Java POI 匯出Excel時檔名中文亂碼,相容瀏覽器
String agent = request.getHeader("USER-AGENT").toLowerCase(); response.setContentType("application/vnd.ms-excel");&
POI匯出excel時,當有大量超連結存在,匯出速度慢
最近修改專案,發現用SXSSF匯出的excel有大量超連結的時候,寫檔案的速度會非常慢 後來查了谷歌,發現是jar包的BUG,不要使用3.10以下的jar包,我用的3.12的jar包就不存在這個問題了
SpringMVC+POI下載檔案模板和匯出Excel
如果檔案模板是固定的,直接放到服務目錄下,然後可以用下面的程式碼下載 <a target="_self" href="/template/template.xlsx" >下載office模版</a> 如果是需要從資料庫查詢出來匯出
POI匯出Excel設定單元格格式2--建立與設定Excel合併單元格
POI建立與設定Excel合併單元格 話不多說上栗子 //準備工作 XSSFWorkbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("sheet1"); XSSFCreationHelper creationHel
POI匯出Excel設定單元格格式
使用Apache的POI相關API匯出Excel設定單元格格式 栗子,一下各個程式碼之間的變數是通用的,要是在某個程式碼塊中找不到某個變數,則可以向上找尋 準備工作 InputStream = template//檔案輸入流 XSSFWorkbook wb = new XSSFW
[置頂]POI操作EXCEL之匯出Excel(設定有效性,下拉列表引用)
//write 2003Excel public static void write2003Excel(String filePath,List list,String[][] data,String str) { try { if
poi匯出excel時,合併單元格後,求和不正確,即“假”合併
excel中所謂“真假”合併單元格 真合併:我們選擇一段連續的單元格,點選合併,這時候,EXCEL會提示如果合併只會顯示第一個單元格的資料,而且其他單元的的資料也會沒掉. 假合併:如果我們用一個已經合併的單元格,格式刷要合併的單元格,這時候沒有提示資料丟失的.事實上,這時候
【慕課實戰】Android高階面試 10大開源框架原始碼解析
程式設計最好的學習方法是閱讀頂尖工程師的原始碼!本課程將帶你深度剖析Android主流開源框架的原始碼,讓你全面掌握框架的使用場景、內部機制、構造原理、核心類、架構與設計思想等,提升你的程式碼閱讀與分析能力、提高程式碼設計能力及改造能力,快速突破技術瓶頸,輕鬆應對Androi
【推薦系統實戰】:C++實現基於用戶的協同過濾(UserCollaborativeFilter)
color style popu ted std 相似度 abi ear result 好早的時候就打算寫這篇文章,可是還是參加阿裏大數據競賽的第一季三月份的時候實驗就完畢了。硬生生是拖到了十一假期。自己也是醉了。。。找工作不是非常順利,希望寫點東西回想一下知識。然後再