日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java導出Execl疑難點處理的實現

瀏覽:22日期:2022-09-02 16:47:50

一.背景

最近業務需求需要導出Execl,最終做出的效果如下,中間牽扯到大量的數據計算。

二.疑難問題分析

Java導出Execl疑難點處理的實現Java導出Execl疑難點處理的實現

問題1:跨單元格處理及邊框設置問題2:自定義背景顏色添加問題3:單元格中部分文字設置顏色問題4:高度自適應處理

三.問題解決

在處理整個Excel導出中總結了很多。

整個開發過程使用的是Apache POI

pom.xml

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.8</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.8</version></dependency>

3.1 HSSFworkbook,XSSFworkbook選哪個

最開始我沿用的是之前開發用的,HSSFworkbook最后發現,HSSFworkbook在處理,自定義單元格背景顏色比較復雜,最后換成了XSSFworkbook。

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,擴展名是.xls;

XSSFWorkbook:是操作Excel2007后的版本,擴展名是.xlsx;

所以在這里我推薦使用XSSFWorkbook

3.2跨單元格及邊框設置

//創建第一行,索引是從0開始的row = sheet.createRow(0);//創建第一個單元格XSSFCell cell0 = row.createCell(0);//設置單元格文字cell0.setCellValue('姓名');//設置單元格樣式cell0.setCellStyle(cellStyleHead);//跨單元格設置//參數為 firstRow, lastRow, firstCol, lastColCellRangeAddress cellRange1 = new CellRangeAddress(0, 1, 0, 0);sheet.addMergedRegion(cellRange1);//注意如果直接在下面寫設置邊框的樣式,可能會出現邊框覆蓋不全的情況,可能是樣式覆蓋問題//所以應該在數據渲染完成之后,在代碼的最后寫跨單元格邊框設置,這是非常重要的

調用設置邊框

//在數據渲染完成,調用封裝的邊框設置方法setRegionStyle(wb, sheet, cellRange1);

設置邊框方法

/** * 合并單元格之后設置邊框 * * @param wb XSSFWorkbook對象 * @param sheet sheet * @param region region */ static void setRegionStyle(XSSFWorkbook wb, XSSFSheet sheet, CellRangeAddress region) { RegionUtil.setBorderTop(1, region, sheet, wb); RegionUtil.setBorderBottom(1, region, sheet, wb); RegionUtil.setBorderLeft(1, region, sheet, wb); RegionUtil.setBorderRight(1, region, sheet, wb); }

3.3自定義背景顏色設置

因為poi自帶的顏色索引可能不滿足我們開發的需求,需要自定義樣色

//創建單元格樣式 XSSFCellStyle cellStyleContent = wb.createCellStyle();//創建背景顏色 226, 239, 218 對應的就是RGB顏色 紅綠藍 cellStyleContent.setFillForegroundColor(new XSSFColor(new java.awt.Color(226, 239, 218)));//填充m cellStyleContent.setFillPattern(CellStyle.SOLID_FOREGROUND);

3.4設置單元格中部分字體顏色

XSSFRichTextString ts = new XSSFRichTextString('123456rn789'); XSSFFont font2 = wb.createFont(); //字體高度font2.setFontHeightInPoints((short) 10);// 字體font2.setFontName('宋體');//字體顏色font2.setColor(HSSFColor.GREEN.index);//那些字體要設置顏色,//int startIndex 開始索引//int endIndex 結束索引// Font font 字體ts.applyFont(5, ts.length(), font2);

3.5高度自適應

封裝的工具類如下,需要在數據渲染完的每行,調用如下工具類

//高度自適應//XSSFRow row;ExcelUtil.calcAndSetRowHeigt(row);

import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.util.CellRangeAddress;import org.apache.poi.xssf.usermodel.*;import java.util.HashMap;import java.util.Map;/** * @author Created by niugang on 2020/3/13/13:34 */public class ExcelUtil { private ExcelUtil() { throw new IllegalStateException('Utility class'); } /** * 根據行內容重新計算行高 * * @param sourceRow sourceRow */ public static void calcAndSetRowHeigt(XSSFRow sourceRow) { for (int cellIndex = sourceRow.getFirstCellNum(); cellIndex <= sourceRow.getPhysicalNumberOfCells(); cellIndex++) { //行高 double maxHeight = sourceRow.getHeight(); XSSFCell sourceCell = sourceRow.getCell(cellIndex); //單元格的內容 String cellContent = getCellContentAsString(sourceCell); if (null == cellContent || ''.equals(cellContent)) {continue; } //單元格的寬高及單元格信息 Map<String, Object> cellInfoMap = getCellInfo(sourceCell); Integer cellWidth = (Integer) cellInfoMap.get('width'); Integer cellHeight = (Integer) cellInfoMap.get('height'); if (cellHeight > maxHeight) {maxHeight = cellHeight; } XSSFCellStyle cellStyle = sourceCell.getCellStyle(); //sourceRow.getSheet().getWorkbook() XSSFFont font = cellStyle.getFont(); //字體的高度 short fontHeight = font.getFontHeight(); //cell內容字符串總寬度 double cellContentWidth = cellContent.getBytes().length * 2 * 256; //字符串需要的行數 不做四舍五入之類的操作 double stringNeedsRows = cellContentWidth / cellWidth; //小于一行補足一行 if (stringNeedsRows < 1.0) {stringNeedsRows = 1.0; } //需要的高度 (Math.floor(stringNeedsRows) - 1) * 40 為兩行之間空白高度 double stringNeedsHeight = (double) fontHeight * stringNeedsRows; //需要重設行高 if (stringNeedsHeight > maxHeight) {maxHeight = stringNeedsHeight;//超過原行高三倍 則為5倍 實際應用中可做參數配置if (maxHeight / cellHeight > 5) { maxHeight = 5 * cellHeight;}//最后取天花板防止高度不夠maxHeight = Math.ceil(maxHeight);//重新設置行高 同時處理多行合并單元格的情況Boolean isPartOfRowsRegion = (Boolean) cellInfoMap.get('isPartOfRowsRegion');if (isPartOfRowsRegion.equals(Boolean.TRUE)) { Integer firstRow = (Integer) cellInfoMap.get('firstRow'); Integer lastRow = (Integer) cellInfoMap.get('lastRow'); //平均每行需要增加的行高 double addHeight = (maxHeight - cellHeight) / (lastRow - firstRow + 1); for (int i = firstRow; i <= lastRow; i++) { double rowsRegionHeight = sourceRow.getSheet().getRow(i).getHeight() + addHeight; rowsRegionHeight=rowsRegionHeight+10; sourceRow.getSheet().getRow(i).setHeight((short) rowsRegionHeight); }} else { maxHeight=maxHeight+10; sourceRow.setHeight((short) maxHeight);} } } } /** * 解析一個單元格得到數據 * * @param cell cell * @return String */ private static String getCellContentAsString(XSSFCell cell) { final String strZero ='.0'; if (null == cell) { return ''; } String result = ''; switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC:String s = String.valueOf(cell.getNumericCellValue());if (s != null) { if (s.endsWith(strZero)) { s = s.substring(0, s.length() - 2); }}result = s;break; case Cell.CELL_TYPE_STRING:result = String.valueOf(cell.getStringCellValue()).trim();break; case Cell.CELL_TYPE_BLANK:break; case Cell.CELL_TYPE_BOOLEAN:result = String.valueOf(cell.getBooleanCellValue());break; case Cell.CELL_TYPE_ERROR:break; default:break; } return result; } /** * 獲取單元格及合并單元格的寬度 * * @param cell cell * @return Map<String , Object> */ private static Map<String, Object> getCellInfo(XSSFCell cell) { XSSFSheet sheet = cell.getSheet(); int rowIndex = cell.getRowIndex(); int columnIndex = cell.getColumnIndex(); boolean isPartOfRegion = false; int firstColumn = 0; int lastColumn = 0; int firstRow = 0; int lastRow = 0; int sheetMergeCount = sheet.getNumMergedRegions(); for (int i = 0; i < sheetMergeCount; i++) { CellRangeAddress ca = sheet.getMergedRegion(i); firstColumn = ca.getFirstColumn(); lastColumn = ca.getLastColumn(); firstRow = ca.getFirstRow(); lastRow = ca.getLastRow(); if (rowIndex >= firstRow && rowIndex <= lastRow) {if (columnIndex >= firstColumn && columnIndex <= lastColumn) { isPartOfRegion = true; break;} } } Map<String, Object> map = new HashMap<>(16); int width = 0; int height = 0; boolean isPartOfRowsRegion = false; if (isPartOfRegion) { for (int i = firstColumn; i <= lastColumn; i++) {width += sheet.getColumnWidth(i); } for (int i = firstRow; i <= lastRow; i++) {height += sheet.getRow(i).getHeight(); } if (lastRow > firstRow) {isPartOfRowsRegion = true; } } else { width = sheet.getColumnWidth(columnIndex); height += cell.getRow().getHeight(); } map.put('isPartOfRowsRegion', isPartOfRowsRegion); map.put('firstRow', firstRow); map.put('lastRow', lastRow); map.put('width', width); map.put('height', height); return map; }}

到此這篇關于Java導出Execl疑難點處理的實現的文章就介紹到這了,更多相關Java導出Execl內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲免费观看| 亚洲欧美成人综合| 亚洲精品黄色| 91麻豆精品激情在线观看最新| 欧美日韩激情| 99精品网站| 夜夜嗨av一区二区三区网站四季av| 亚洲主播在线| 日韩欧美激情电影| 国产精品115| 色综合狠狠操| 九色精品91| 亚洲香蕉久久| 免费日韩成人| 久久激情网站| 蜜臀av国产精品久久久久| 91伊人久久| 国产日韩免费| 日韩一区电影| 蜜臀av国产精品久久久久 | 日本久久成人网| 亚洲国产不卡| 国产日韩欧美一区二区三区在线观看| 久久一区精品| 亚洲激情中文| 国产精品主播在线观看| 欧美日韩国产v| 丝袜脚交一区二区| 欧美激情在线精品一区二区三区| 欧洲亚洲一区二区三区| 亚洲精品在线二区| 日韩a一区二区| 宅男噜噜噜66国产日韩在线观看| 免费久久99精品国产| 久久99久久久精品欧美| 激情综合激情| 国产精品久久久一区二区| 久久蜜桃资源一区二区老牛| 亚洲精品免费观看| av高清不卡| 欧美专区一区| 日韩视频不卡| 国产成人免费| 日韩av中文在线观看| 成人自拍av| 色婷婷成人网| 91精品国产成人观看| 999在线观看精品免费不卡网站| 国产欧美日韩一级| 欧美资源在线| 日韩欧美一区二区三区在线视频 | 亚洲播播91| 久久精品超碰| 精品1区2区3区4区| 成人在线视频区| 69堂免费精品视频在线播放| 在线精品视频在线观看高清| 国产精品白浆| 亚洲a级精品| 久久影院一区| 福利视频一区| 综合五月婷婷| 亚洲高清影视| 97国产精品| 国产精品啊v在线| 日韩国产精品久久久| 日韩午夜电影| 免费国产自久久久久三四区久久 | 国产伊人久久| 国产精品中文字幕亚洲欧美| 蜜臀久久99精品久久久久久9| 久久高清免费| 日韩精品诱惑一区?区三区| 麻豆精品在线视频| 久久精品av麻豆的观看方式| 欧美日韩国产免费观看视频| 福利在线免费视频| 国产精品sss在线观看av| 亚洲精品大片| 蜜桃视频一区二区| 视频在线观看91| 亚洲一区二区动漫| 亚洲一区亚洲| 午夜在线一区| 丝袜国产日韩另类美女| 亚洲欧美日韩专区| av不卡在线看| aⅴ色国产欧美| 亚洲综合三区| 蜜桃视频一区二区| 午夜国产一区二区| 国产精品免费看| 国产偷自视频区视频一区二区| 黑丝美女一区二区| 亚洲国产日韩欧美在线| 免费不卡中文字幕在线| 图片区亚洲欧美小说区| 亚洲激情二区| 亚洲免费在线| 红桃视频国产精品| 久久成人一区| 日韩一区二区三区四区五区| 亚洲精品激情| 日本va欧美va精品发布| 日本中文字幕不卡| 欧美91精品| 欧美特黄一级| 一区二区高清| 视频一区中文字幕精品| 国产亚洲高清一区| 成人污污视频| 久久精品国产68国产精品亚洲| 激情欧美国产欧美| 亚洲久久视频| 美女在线视频一区| 999国产精品999久久久久久| 中日韩男男gay无套| 日韩综合一区二区三区| 国产精品xvideos88| 亚洲一区资源| 天堂√中文最新版在线| 欧美日中文字幕| 中文字幕亚洲精品乱码| 日韩精品福利一区二区三区| 欧美国产视频| 亚洲视频综合| 青青草91视频| 久久久精品五月天| 亚洲精品伊人| 国产成人调教视频在线观看| 亚洲成人二区| 日韩美女国产精品| jizzjizz中国精品麻豆| 国产亚洲毛片| 国产精品二区影院| 久久精品免费看| 国产亚洲精品v| 国产精品成人国产| 免费毛片在线不卡| 国产乱码精品一区二区三区四区 | 免费成人在线观看| 国产精品tv| 精品一区三区| 亚洲人成在线影院| 高潮久久久久久久久久久久久久| 国产亚洲精品v| 国产一区二区三区不卡av| 一区视频在线| 国产一区二区三区成人欧美日韩在线观看| 欧美午夜不卡影院在线观看完整版免费| 欧美一区影院| 精品一区亚洲| 岛国av免费在线观看| 日韩一区二区三免费高清在线观看| 欧美一级鲁丝片| 欧美日韩一区二区三区在线电影| 亚洲天堂1区| 国产精品乱战久久久| 1024精品一区二区三区| 久久精品资源| 婷婷综合一区| 91久久国产| 鲁鲁在线中文| 国产精品乱战久久久| 亚洲深爱激情| 日韩欧美午夜| 国产精品亚洲综合在线观看| 国产偷自视频区视频一区二区| 精品美女在线视频| 日韩美女国产精品| 男女精品网站| 激情欧美一区二区三区| 日韩av自拍| 日韩在线观看一区二区三区| 欧美日韩国产传媒| 美女一区网站| 国产精品久久久网站| 中文字幕一区二区av| 影视先锋久久| 日韩电影免费在线观看| 国产精区一区二区| 综合日韩在线| 首页亚洲欧美制服丝腿| 亚洲女同中文字幕| 久久久久久久久久久妇女| 高清一区二区| 国产精品1luya在线播放| 日本精品在线播放| 91精品国产乱码久久久久久久| 动漫av一区| 久久久久九九精品影院| 国产伦理一区| 国产日韩欧美中文在线| 亚洲人www| 黄页网站一区| 宅男在线一区| 伊人精品在线| 亚洲少妇诱惑| 美国三级日本三级久久99| 免费欧美日韩|