POI Excel 转 HTML(兼容2003和2007)

发布时间:2019-07-30作者:laosun阅读(2000)

POI

    POI Excel 转 HTML(兼容2003和2007),附带测试类

    PoiExcelToHtml.java

    其中的缺失类都不重要,自己修改下即可

    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    import java.text.DecimalFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    
    import org.apache.log4j.Logger;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFDataFormat;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFPalette;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.XSSFCellStyle;
    import org.apache.poi.xssf.usermodel.XSSFColor;
    import org.apache.poi.xssf.usermodel.XSSFFont;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import com.google.common.collect.Maps;
    import com.xxxx.common.constants.ResultConstants;
    import com.xxxx.common.utils.LogKit;
    import com.xxxx.pojos.Result;
    import com.jfinal.kit.JsonKit;
    
    /**
     * Excel 转 HTML
     * 
     * @author sun
     */
    public class PoiExcelToHtml {
    
    	protected static final Logger LOG = Logger.getLogger(PoiExcelToHtml.class);
    	
    	static String[] bordesr = { "border-top:", "border-right:", "border-bottom:", "border-left:" };
    	static String[] borderStyles = { "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid", "solid", "solid", "solid", "solid" };
    
    	@SuppressWarnings("rawtypes")
    	public static void main(String args[]) throws Exception {
    		//============================================================转换远程excel============================================================
    		String url = "http://192.168.1.1/doc/raw/master/xxxx/xxxx.xlsx";
    		Map<String, String> map = Maps.newHashMap();
    		map.put("cookie", "_gitlab_session=3c0aa7d2ceb3725bf578eb47533e0191");
    		map.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
    		map.put("Accept-Encoding", "gzip, deflate, sdch");
    		map.put("Accept-Language", "zh-CN,zh;q=0.8");
    		map.put("Cache-Control", "max-age=0");
    		map.put("Connection", "keep-alive");
    		Result remoteResult = remoteExcelToHtml(url, map, true, true);
    		if(ResultConstants.RESULT_CODE_SUCCESS.equals(remoteResult.getCode())) {
    			//写入本地文件
    			String content = remoteResult.getData().toString();
    			org.apache.commons.io.FileUtils.writeStringToFile(new File("/Users/sun/Downloads/", "remoteIndex.html"), content, "utf-8");
    		}
    		LOG.info(LogKit.append("远程excel转html", JsonKit.toJson(remoteResult)));
    		//============================================================转换本地excel============================================================
    		//转换本地excel
    		Result localResult = localExcelToHtml("/Users/sun/Downloads/import_template.xls", true, true);
    		if(ResultConstants.RESULT_CODE_SUCCESS.equals(localResult.getCode())) {
    			//写入本地文件
    			String content = localResult.getData().toString();
    			org.apache.commons.io.FileUtils.writeStringToFile(new File("/Users/sun/Downloads/localIndex.html"), content, "utf-8");
    		}
    		LOG.info(LogKit.append("本地excel转html", JsonKit.toJson(localResult)));
    	}
    	
    	/**
    	 * 读取远程excel
    	 * @param remoteUrl
    	 * @param headers
    	 * @param isWithStyle
    	 * @return
    	 */
    	@SuppressWarnings("rawtypes")
    	public static Result remoteExcelToHtml(String remoteUrl, Map<String, String> headers, boolean isShowSheet, boolean isWithStyle) {
    		Result result = new Result();
    		try {
    			URLConnection conn = new URL(remoteUrl).openConnection();
    			conn.setConnectTimeout(10000);//默认链接超时10秒
    			conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36");
    			if (headers != null && !headers.isEmpty()) {
    				for (Entry<String, String> entry : headers.entrySet()) {
    					conn.setRequestProperty(entry.getKey(), entry.getValue());
    				}
    			}
    			InputStream is = conn.getInputStream();
    			result = excelToHtml(remoteUrl, is, isShowSheet, isWithStyle);
    			return result;
    		}catch (Exception e) {
    			e.printStackTrace();
    			LOG.error(LogKit.append("远程读取excel", "出现异常", remoteUrl, e.getMessage()));
    			result.setCode(ResultConstants.RESULT_CODE_FAILED);
    			result.setMsg(e.getMessage());
    			return result;
    		}
    	}
    	
    	/**
    	 * 读取本地excel
    	 * @param filepath
    	 * @param isWithStyle
    	 * @return
    	 */
    	@SuppressWarnings("rawtypes")
    	public static Result localExcelToHtml(String filepath, boolean isShowSheet, boolean isWithStyle) {
    		Result result = new Result();
    		try {
    			InputStream is = new FileInputStream(filepath);
    			result = excelToHtml(filepath, is, isShowSheet, isWithStyle);
    			return result;
    		}catch (Exception e) {
    			e.printStackTrace();
    			LOG.error(LogKit.append("本地读取excel", "出现异常", filepath, e.getMessage()));
    			result.setCode(ResultConstants.RESULT_CODE_FAILED);
    			result.setMsg(e.getMessage());
    			return result;
    		}
    	}
    
    	/**
    	 * 将excel流转换成 html table
    	 * @param is
    	 * @param isWithStyle
    	 * @return
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	private static Result excelToHtml(String file, InputStream is, boolean isShowSheet, boolean isWithStyle) {
    		Result result = new Result();
    		Workbook workbook = null;
    		try {
    			long s = System.currentTimeMillis();
    			String suffix = file.substring(file.lastIndexOf(".")+1, file.length());
    			if("xlsx".equalsIgnoreCase(suffix)) {// 07 excel
    				workbook = new XSSFWorkbook(is);
    			}else if("xls".equalsIgnoreCase(suffix)) {// 03 excel
    				workbook = new HSSFWorkbook(is);
    			}else {
    				//不支持此类型
    				result.setCode(ResultConstants.RESULT_CODE_FAILED);
    				result.setMsg("不支持的文件类型");
    				return result;
    			}
    			StringBuffer sb = new StringBuffer();
    			Sheet sheet = workbook.getSheetAt(0);// 获取第一个Sheet的内容
    			Map<String, String> map[] = getRowSpanColSpanMap(sheet);
    			int lastRowNum = sheet.getLastRowNum();
    			//转换处理方式
    			for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
    				org.apache.poi.ss.usermodel.Sheet sheet1 = workbook.getSheetAt(numSheet);
    				if (sheet1 == null) {
    					continue;
    				}
    				if (numSheet != 0) {
    					sb.append("<br><br>");
    				}
    				if(isShowSheet) {
    					sb.append("<div style='font-size: 25px;text-align: center;margin-bottom: 20px;font-weight: bold;text-decoration: underline;'>" + sheet1.getSheetName() + "</div>");
    				}
    				sb.append("<table style='border-collapse:collapse;' width='100%'>");
    
    				Row row = null;
    				Cell cell = null;
    				for (int rowNum = sheet1.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
    					row = sheet1.getRow(rowNum);
    					if (row == null) {
    						// sheet空间
    						continue;
    					}
    					boolean flag = false;
    					StringBuffer rowHtml = new StringBuffer();
    					rowHtml.append("<tr>");
    					int lastColNum = row.getLastCellNum();
    					for (int colNum = 0; colNum < lastColNum; colNum++) {
    						cell = row.getCell(colNum);
    						if (cell == null) { // 特殊情况 空白的单元格会返回null
    //							rowHtml.append("<td>&nbsp;</td>");
    							continue;
    						}
    
    						String stringValue = getCellValue(cell);
    						if (map[0].containsKey(rowNum + "," + colNum)) {
    							String pointString = map[0].get(rowNum + "," + colNum);
    							map[0].remove(rowNum + "," + colNum);
    							int bottomeRow = Integer.valueOf(pointString.split(",")[0]);
    							int bottomeCol = Integer.valueOf(pointString.split(",")[1]);
    							int rowSpan = bottomeRow - rowNum + 1;
    							int colSpan = bottomeCol - colNum + 1;
    							rowHtml.append("<td rowspan= '" + rowSpan + "' colspan= '" + colSpan + "' ");
    						} else if (map[1].containsKey(rowNum + "," + colNum)) {
    							map[1].remove(rowNum + "," + colNum);
    							continue;
    						} else {
    							rowHtml.append("<td ");
    						}
    						// 判断是否需要样式
    						if (isWithStyle) {
    							dealExcelStyle(workbook, sheet1, cell, rowHtml);// 处理单元格样式
    						}
    
    						rowHtml.append(">");
    						if (stringValue == null || "".equals(stringValue.trim())) {
    							rowHtml.append(" &nbsp; ");
    						} else {
    							// 将ascii码为160的空格转换为html下的空格(&nbsp;)
    							rowHtml.append(stringValue.replace(String.valueOf((char) 160), "&nbsp;"));
    							flag = true;
    						}
    						rowHtml.append("</td>");
    					}
    					rowHtml.append("</tr>");
    					if (flag) {//如果excel 行无数据,则不拼接tr
    						sb.append(rowHtml);
    					}
    				}
    				sb.append("</table>");
    				ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    				DOMSource domSource = new DOMSource();
    				StreamResult streamResult = new StreamResult(outStream);
    				TransformerFactory tf = TransformerFactory.newInstance();
    				Transformer serializer = tf.newTransformer();
    				serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
    				serializer.setOutputProperty(OutputKeys.INDENT, "yes");
    				serializer.setOutputProperty(OutputKeys.METHOD, "html");
    				serializer.transform(domSource, streamResult);
    				outStream.close();
    			}
    			result.setData(sb.toString());
    			long e = System.currentTimeMillis();
    			LOG.info(LogKit.append("excel转HTML已完成", "共耗时 " + (e - s) + " 毫秒"));
    		} catch (NotOfficeXmlFileException e) {
    			e.printStackTrace();
    			LOG.error(LogKit.append("excel转html", "出现异常", e.getMessage()));
    			result.setCode(ResultConstants.RESULT_CODE_FAILED);
    			result.setMsg(e.getMessage());
    			return result;
    		} catch (Exception e) {
    			e.printStackTrace();
    			LOG.error(LogKit.append("excel转html", "出现异常", e.getMessage()));
    			result.setCode(ResultConstants.RESULT_CODE_FAILED);
    			result.setMsg(e.getMessage());
    			return result;
    		}
    		return result;
    	}
    
    	/**
    	 * 获取表格单元格Cell内容
    	 * 
    	 * @param cell
    	 * @return
    	 */
    	@SuppressWarnings("deprecation")
    	private static String getCellValue(Cell cell) {
    		String result = new String();
    		switch (cell.getCellType()) {
    		case Cell.CELL_TYPE_NUMERIC:// 数字类型
    			if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
    				SimpleDateFormat sdf = null;
    				if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
    					sdf = new SimpleDateFormat("HH:mm");
    				} else {// 日期
    					sdf = new SimpleDateFormat("yyyy-MM-dd");
    				}
    				Date date = cell.getDateCellValue();
    				result = sdf.format(date);
    			} else if (cell.getCellStyle().getDataFormat() == 58) {
    				// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
    				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    				double value = cell.getNumericCellValue();
    				Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value);
    				result = sdf.format(date);
    			} else {
    				double value = cell.getNumericCellValue();
    				CellStyle style = cell.getCellStyle();
    				DecimalFormat format = new DecimalFormat();
    				String temp = style.getDataFormatString();
    				// 单元格设置成常规
    				if (temp.equals("General")) {
    					format.applyPattern("#");
    				}
    				result = format.format(value);
    			}
    			break;
    		case Cell.CELL_TYPE_STRING:// String类型
    			result = cell.getRichStringCellValue().toString();
    			break;
    		case Cell.CELL_TYPE_BLANK:
    			result = "";
    			break;
    		default:
    			result = "";
    			break;
    		}
    		return result;
    	}
    
    	/**
    	 * 处理表格样式
    	 * @param wb
    	 * @param sheet
    	 * @param cell
    	 * @param sb
    	 */
    	@SuppressWarnings("deprecation")
    	private static void dealExcelStyle(Workbook wb, Sheet sheet, Cell cell, StringBuffer sb) {
    		CellStyle cellStyle = cell.getCellStyle();
    		if (cellStyle != null) {
    			short alignment = cellStyle.getAlignment();
    			sb.append("align='" + convertAlignToHtml(alignment) + "' ");// 单元格内容的水平对齐方式
    			short verticalAlignment = cellStyle.getVerticalAlignment();
    			sb.append("valign='" + convertVerticalAlignToHtml(verticalAlignment) + "' ");// 单元格中内容的垂直排列方式
    			if (wb instanceof XSSFWorkbook) {
    				XSSFFont xf = ((XSSFCellStyle) cellStyle).getFont();
    				short boldWeight = xf.getBoldweight();
    				sb.append("style='");
    				sb.append("font-weight:" + boldWeight + ";"); // 字体加粗
    				sb.append("font-size: " + xf.getFontHeight() / 2 + "%;"); // 字体大小
    				int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
    				sb.append("width:" + columnWidth + "px;");
    				XSSFColor xc = xf.getXSSFColor();
    				if (xc != null) {
    					sb.append("color:#" + xc.getARGBHex().substring(2) + ";"); // 字体颜色
    				}
    				XSSFColor bgColor = (XSSFColor) cellStyle.getFillForegroundColorColor();
    				if (bgColor != null) {
    					sb.append("background-color:#" + bgColor.getARGBHex().substring(2) + ";"); // 背景颜色
    				}
    				sb.append(getBorderStyle(0, cellStyle.getBorderTop(), ((XSSFCellStyle) cellStyle).getTopBorderXSSFColor()));
    				sb.append(getBorderStyle(1, cellStyle.getBorderRight(), ((XSSFCellStyle) cellStyle).getRightBorderXSSFColor()));
    				sb.append(getBorderStyle(2, cellStyle.getBorderBottom(), ((XSSFCellStyle) cellStyle).getBottomBorderXSSFColor()));
    				sb.append(getBorderStyle(3, cellStyle.getBorderLeft(), ((XSSFCellStyle) cellStyle).getLeftBorderXSSFColor()));
    			} else if (wb instanceof HSSFWorkbook) {
    				HSSFFont hf = ((HSSFCellStyle) cellStyle).getFont(wb);
    				short boldWeight = hf.getBoldweight();
    				short fontColor = hf.getColor();
    				sb.append("style='");
    				HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette(); // 类HSSFPalette用于求的颜色的国际标准形式
    				HSSFColor hc = palette.getColor(fontColor);
    				sb.append("font-weight:" + boldWeight + ";"); // 字体加粗
    				sb.append("font-size: " + hf.getFontHeight() / 2 + "%;"); // 字体大小
    				String fontColorStr = convertToStardColor(hc);
    				if (fontColorStr != null && !"".equals(fontColorStr.trim())) {
    					sb.append("color:" + fontColorStr + ";"); // 字体颜色
    				}
    				int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
    				sb.append("width:" + columnWidth + "px;");
    				short bgColor = cellStyle.getFillForegroundColor();
    				hc = palette.getColor(bgColor);
    				String bgColorStr = convertToStardColor(hc);
    				if (bgColorStr != null && !"".equals(bgColorStr.trim())) {
    					sb.append("background-color:" + bgColorStr + ";"); // 背景颜色
    				}
    				sb.append(getBorderStyle(palette, 0, cellStyle.getBorderTop(), cellStyle.getTopBorderColor()));
    				sb.append(getBorderStyle(palette, 1, cellStyle.getBorderRight(), cellStyle.getRightBorderColor()));
    				sb.append(getBorderStyle(palette, 3, cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor()));
    				sb.append(getBorderStyle(palette, 2, cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor()));
    			}
    			sb.append("' ");
    		}
    	}
    
    	/**
    	 * 单元格内容的水平对齐方式
    	 * 
    	 * @param alignment
    	 * @return
    	 */
    	@SuppressWarnings("deprecation")
    	private static String convertAlignToHtml(short alignment) {
    		String align = "left";
    		switch (alignment) {
    		case CellStyle.ALIGN_LEFT:
    			align = "left";
    			break;
    		case CellStyle.ALIGN_CENTER:
    			align = "center";
    			break;
    		case CellStyle.ALIGN_RIGHT:
    			align = "right";
    			break;
    		default:
    			break;
    		}
    		return align;
    	}
    
    	/**
    	 * 单元格中内容的垂直排列方式
    	 * 
    	 * @param verticalAlignment
    	 * @return
    	 */
    	@SuppressWarnings("deprecation")
    	private static String convertVerticalAlignToHtml(short verticalAlignment) {
    		String valign = "middle";
    		switch (verticalAlignment) {
    		case CellStyle.VERTICAL_BOTTOM:
    			valign = "bottom";
    			break;
    		case CellStyle.VERTICAL_CENTER:
    			valign = "center";
    			break;
    		case CellStyle.VERTICAL_TOP:
    			valign = "top";
    			break;
    		default:
    			break;
    		}
    		return valign;
    	}
    
    	@SuppressWarnings("deprecation")
    	private static String convertToStardColor(HSSFColor hc) {
    		StringBuffer sb = new StringBuffer("");
    		if (hc != null) {
    			if (HSSFColor.AUTOMATIC.index == hc.getIndex()) {
    				return null;
    			}
    			sb.append("#");
    			for (int i = 0; i < hc.getTriplet().length; i++) {
    				sb.append(fillWithZero(Integer.toHexString(hc.getTriplet()[i])));
    			}
    		}
    		return sb.toString();
    	}
    
    	private static String fillWithZero(String str) {
    		if (str != null && str.length() < 2) {
    			return "0" + str;
    		}
    		return str;
    	}
    
    	private static String getBorderStyle(HSSFPalette palette, int b, short s, short t) {
    		if (s == 0){
    			return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
    		}
    		String borderColorStr = convertToStardColor(palette.getColor(t));
    		borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr;
    		return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
    
    	}
    
    	private static String getBorderStyle(int b, short s, XSSFColor xc) {
    		if (s == 0) {
    			return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
    		}
    		if (xc != null) {
    			String borderColorStr = xc.getARGBHex();// t.getARGBHex();
    			borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr.substring(2);
    			return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
    		}
    		return "";
    	}
    
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	private static Map<String, String>[] getRowSpanColSpanMap(Sheet sheet) {
    		Map<String, String> map0 = new HashMap<String, String>();
    		Map<String, String> map1 = new HashMap<String, String>();
    		int mergedNum = sheet.getNumMergedRegions();
    		CellRangeAddress range = null;
    		for (int i = 0; i < mergedNum; i++) {
    			range = sheet.getMergedRegion(i);
    			int topRow = range.getFirstRow();
    			int topCol = range.getFirstColumn();
    			int bottomRow = range.getLastRow();
    			int bottomCol = range.getLastColumn();
    			map0.put(topRow + "," + topCol, bottomRow + "," + bottomCol);
    			int tempRow = topRow;
    			while (tempRow <= bottomRow) {
    				int tempCol = topCol;
    				while (tempCol <= bottomCol) {
    					map1.put(tempRow + "," + tempCol, "");
    					tempCol++;
    				}
    				tempRow++;
    			}
    			map1.remove(topRow + "," + topCol);
    		}
    		Map[] map = { map0, map1 };
    		return map;
    	}
    
    }


2 +1

版权声明

 Java  源码  开源  apache

 请文明留言

0 条评论