国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn)

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

一.背景

最近業(yè)務(wù)需求需要導(dǎo)出Execl,最終做出的效果如下,中間牽扯到大量的數(shù)據(jù)計(jì)算。

二.疑難問題分析

Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn)Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn)

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

三.問題解決

在處理整個(gè)Excel導(dǎo)出中總結(jié)了很多。

整個(gè)開發(fā)過程使用的是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選哪個(gè)

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

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

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

所以在這里我推薦使用XSSFWorkbook

3.2跨單元格及邊框設(shè)置

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

調(diào)用設(shè)置邊框

//在數(shù)據(jù)渲染完成,調(diào)用封裝的邊框設(shè)置方法setRegionStyle(wb, sheet, cellRange1);

設(shè)置邊框方法

/** * 合并單元格之后設(shè)置邊框 * * @param wb XSSFWorkbook對(duì)象 * @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自定義背景顏色設(shè)置

因?yàn)閜oi自帶的顏色索引可能不滿足我們開發(fā)的需求,需要自定義樣色

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

3.4設(shè)置單元格中部分字體顏色

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

3.5高度自適應(yīng)

封裝的工具類如下,需要在數(shù)據(jù)渲染完的每行,調(diào)用如下工具類

//高度自適應(yīng)//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'); } /** * 根據(jù)行內(nèi)容重新計(jì)算行高 * * @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); //單元格的內(nèi)容 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內(nèi)容字符串總寬度 double cellContentWidth = cellContent.getBytes().length * 2 * 256; //字符串需要的行數(shù) 不做四舍五入之類的操作 double stringNeedsRows = cellContentWidth / cellWidth; //小于一行補(bǔ)足一行 if (stringNeedsRows < 1.0) {stringNeedsRows = 1.0; } //需要的高度 (Math.floor(stringNeedsRows) - 1) * 40 為兩行之間空白高度 double stringNeedsHeight = (double) fontHeight * stringNeedsRows; //需要重設(shè)行高 if (stringNeedsHeight > maxHeight) {maxHeight = stringNeedsHeight;//超過原行高三倍 則為5倍 實(shí)際應(yīng)用中可做參數(shù)配置if (maxHeight / cellHeight > 5) { maxHeight = 5 * cellHeight;}//最后取天花板防止高度不夠maxHeight = Math.ceil(maxHeight);//重新設(shè)置行高 同時(shí)處理多行合并單元格的情況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);} } } } /** * 解析一個(gè)單元格得到數(shù)據(jù) * * @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; }}

到此這篇關(guān)于Java導(dǎo)出Execl疑難點(diǎn)處理的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java導(dǎo)出Execl內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 国产精品一区在线播放 | 91精品乱码一区二区三区 | 宫女淫春3在线观 | 亚洲第一区精品日韩在线播放 | 国产丝袜不卡一区二区 | 性生话一级国产片 | 国产精品午夜性视频 | 亚洲综合网在线 | 欧美国产精品亚洲精品第一区 | 日本一级特黄大一片免 | 久久99国产乱子伦精品免 | 欧美日韩国产一区二区三区在线观看 | 国产大片线上免费看 | 国产视频高清在线 | a毛片免费在线观看 | 古代级a毛片在线 | 久久久久久久久久久9精品视频 | 日韩欧美国产成人 | 欧美精品v日韩精品v国产精品 | 视频一区二区在线 | 一本综合久久国产二区 | 亚洲一区二区中文字幕 | 欧美日韩性视频一区二区三区 | 国产情侣真实露脸在线最新 | 亚洲久久天堂 | 手机看片精品高清国产日韩 | 国产67194 | 国产三级a | 国产午夜精品久久久久九九 | 深夜福利视频在线观看免费视频 | 手机在线一区二区三区 | 欧美在线a| 91成人国产福利 | 久久久久久九九 | 午夜成年人网站 | 国产美女精品视频免费观看 | 91精品欧美一区二区综合在线 | 中文字幕曰韩一区二区不卡 | 日韩中文字幕精品一区在线 | 美女一级片 | 国产精品亚洲第五区在线 |