本期咱们讲一下java导出excel的常见的打开异常问题;
常见的问题包括以下几个问题:

  1. excel打开后是黑底
  2. excel 提示打开是损坏的
  3. 实际是xlsx ,但是后缀显示xls或者实际是xls但是后缀是xlsx
    上面的这些问题一般会出现在用office打开excel时用WPS打开一般不会出现。这里就有一个问题为什么会出现这个问题,这是由于WPS兼容了office的历史版本功能,
    所以对于任何版本的excelWPS都能打开。而office由于存在office2003及以前版本和office2007及以后版本的问题所以会出现以上问题。从这个角度来看WPS的后发优势以及
    兼容性广就体现出来了。回到问题我们来看一下以上问题如何解决。

一、excel打开后是黑底
对于excel打开后是黑底这个问题,是由于office在打开时如果不设置底色时会出现默认为黑色的问题,具体来看代码:

/**
	 * 向模板中写入数据
	 * @param index
	 * @param obj
	 * @param sheet
	 * @throws IntrospectionException
	 */
	public static void writeData (int index, Object obj, Sheet sheet) throws IntrospectionException {
		Row row = getRow(sheet, index + 1);
		// 序号
		row.createCell(0).setCellValue(index + 1);
		//单元格样式
		CellStyle cellStyle = getCellStyle("DEFAULT", sheet, false);
		// 填充序号
		Cell cell1 = getCell(row, 0);
		cell1.setCellValue(index + 1);
		cell1.setCellStyle(cellStyle);
		// 获取当前对象上有注解的属性进行导出
		Class clazz = obj.getClass();
		// 获取对象属性
		Field[] fields = clazz.getDeclaredFields();
		int n = 1;
		for (Field field : fields) {
			field.setAccessible(true); // 私有属性必须设置访问权限
			PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
			Method getMethod = pd.getReadMethod();//获得get方法
			Object resultValue = ReflectionUtils.invokeMethod(getMethod, obj);
			ExcelField annotation = field.getAnnotation(ExcelField.class);
			if (annotation == null) {
				continue;
			}
			int comment = annotation.column();
			Cell cell = row.createCell(comment);
			cell.setCellValue(null == resultValue ? "" : String.valueOf(resultValue));
			cell.setCellStyle(cellStyle);
			n++;
		}
	}
	
	public static CellStyle getCellStyle(String type, Sheet sheet, boolean isBold) {
		Workbook workbook = sheet.getWorkbook();
		XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
		// 填充边框
		cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
		cellStyle.setBorderRight(BorderStyle.THIN);//右边框
		cellStyle.setBorderTop(BorderStyle.THIN);//右边框
		cellStyle.setBorderLeft(BorderStyle.THIN);//右边框
        // 水平对齐方式
        cellStyle.setAlignment(HorizontalAlignment.LEFT);
        // 垂直对齐方式
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		//设置字体加粗
		if (isBold) {
			org.apache.poi.ss.usermodel.Font font = workbook.createFont();
			//粗体显示
			font.setBold(isBold);
			//设置字体格式
			cellStyle.setFont(font);
		}
		return cellStyle;
	}

解决方法:excel设置样式时给个底色就可以了;

/**
	 * 设置单元格样式
	 * @param sheet
	 * @param isBold
	 * @return
	 */
	public static CellStyle getCellStyle(String type, Sheet sheet, boolean isBold) {
		Integer[] colorRGB = getColorRGB("DEFAULT");
		java.awt.Color color = new java.awt.Color(colorRGB[0], colorRGB[1], colorRGB[2]);
		Workbook workbook = sheet.getWorkbook();
		XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
		// 设置填充颜色
		XSSFColor fillColor = new XSSFColor(color);
		cellStyle.setFillForegroundColor(fillColor);
		cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		// 填充边框
		cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
		cellStyle.setBorderRight(BorderStyle.THIN);//右边框
		cellStyle.setBorderTop(BorderStyle.THIN);//右边框
		cellStyle.setBorderLeft(BorderStyle.THIN);//右边框
        // 水平对齐方式
        cellStyle.setAlignment(HorizontalAlignment.LEFT);
        // 垂直对齐方式
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		//设置字体加粗
		if (isBold) {
			org.apache.poi.ss.usermodel.Font font = workbook.createFont();
			//粗体显示
			font.setBold(isBold);
			//设置字体格式
			cellStyle.setFont(font);
		}
		return cellStyle;
	}

单元格的颜色设设置的时候,有背景颜色设置方法[setFillBackgroundColor()]和前景颜色设置方法[setFillForegroundColor()];设置的时候要区别开,根据需要调用相应的方法;

关于背景颜色和前景颜色:

前景颜色:一般指字体颜色

背景颜色:一般指单元格的填充颜色

 // 设置背景颜色
 style.setFillBackgroundColor(new HSSFColor.WHITE().getIndex());
 //设置前景颜色 修复wps展示正常,office展示变黑问题
 style.setFillForegroundColor(new HSSFColor.WHITE().getIndex());

这里还隐藏了一个问题就是填充颜色不成功的问题:

注意点:单元格设置背景颜色失效原因/不生效的原因,通常是因为只设置了setFillForegroundColor 参数,这样肯定是不行的,还需要再设置一下 setFillPattern,在setFillPattern中添加FillPatternType.SOLID_FOREGROUND即可

cellStyle.setFillForegroundColor(****)
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

方法1 - 使用默认的自定义颜色:

cellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

通过获取IndexedColors的不同值来更改颜色(默认颜色对照表在文章底部)

方法2 - 使用rgb方法自定义 :

/**
 * 标题背景色
 */
private static final String DEFAULT_BACKGROUND_COLOR = "#9BC2E6";
// 自定义背景色
int r = Integer.parseInt((DEFAULT_BACKGROUND_COLOR.substring(1,3)),16);
int g = Integer.parseInt((DEFAULT_BACKGROUND_COLOR.substring(3,5)),16);
int b = Integer.parseInt((DEFAULT_BACKGROUND_COLOR.substring(5,7)),16);
 
HSSFWorkbook wb = new HSSFWorkbook();
HSSFPalette palette = wb.getCustomPalette();
HSSFColor hssfColor = palette.findSimilarColor(r, g, b);
 
// 背景色与填充
cellStyle.setFillForegroundColor(hssfColor.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

扩展:第二种rgb的方式自定义颜色使用的是HSSFColor,HSSFColor跟IndexedColors一样都是本身支持的一些默认颜色,代码过程就是使用16进制根据下标切割 #9BC2E6 ,再进行转换添加到HSSFColor默认颜色中

二、excel 提示打开是损坏的
这里就是由于office版本不能向上兼容而导致的问题;
一定要注意HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook的区别:

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

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

SXSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx;

注意:1、HSSFWorkbook和XSSFWorkbook对应的扩展名必须严格按照要求来,同时更改文档扩展名时必须用另存为不能直接修改后缀:.xls另存为.xlsx而不是手动修改后缀;
2、HSSFWorkbook和XSSFWorkbook可以向下兼容不能向上兼容因此建议使用XSSFWorkbook;

三、实际是xlsx ,但是后缀显示xls或者实际是xls但是后缀是xlsx
解决方法:更改文档扩展名时必须用另存为不能直接修改后缀:.xls另存为.xlsx而不是手动修改后缀

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐