Spring4.1.1升级到4.3.9遇到的问题与解决方法
1、 页面显示样式、图片、js文件失效
在4.1.1下配置为:
<mvc:resources location="/static/**" mapping="/static/**"/>
但是在4.3.9下页面样式显示丢失,经反复查询资料与测试,发现采用如下方式可以解决此问题,修改配置为(其中res可自定义,就是不能使用static,郁闷):
<mvc:resources location="/res/" mapping="/res/**"/>
或者干脆将资源文件夹改名为“resources”即可生效,不用进行任何配置。
2、 输出Excel文件时AbstractExcelView过期的处理方法
在4.3.9中输出Excel文件时,AbstractExcelView过期,新增AbstractXlsView、AbstractXlsxView及AbstractXlsxStreamingView;在这里我采用的是AbstractXlsView生成Excel2003文件,代码如下:
package cn.xaele...;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Footer;
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.springframework.web.servlet.view.document.AbstractXlsView;
import cn.xaele.kq.psm.bean.KqTechnical;
import cn.xaele.utils.PoiUtils;
/**
* “职称” Excel文档输出控制类
*
* @author taotao
* @since 2016-10-04 15:50
* @version 1.0.0
*/
public class KqTechnical_ExcelView extends AbstractXlsView {
// 日志输出
private static final Logger log = LogManager.getLogger(KqTechnical_ExcelView.class);
// 测试标记
private boolean isTest = true;
// 设置输出列表题头内容
private String[] fieldName = { "序号", "职称名称", "备注" };
/**
* 输出所有 职称 信息 @param model @param workBook @param request @param
* response @throws
*/
public void buildExcelDocument(Map<String, Object> model, Workbook workBook, HttpServletRequest request,
HttpServletResponse response) throws Exception {
// 接收传递过来的数据f
@SuppressWarnings("unchecked")
List<KqTechnical> objList = (List<KqTechnical>) model.get("objList");
if (objList == null) {
objList = new ArrayList<KqTechnical>();
}
if (isTest) {
log.info("list.size()-------------->" + objList.size());
}
String saveFileName = "KqTechnicalRpt";
int rowNum = 0;
int cellNum = 0;
try {
workBook = new HSSFWorkbook();
Sheet sheet = workBook.createSheet("Sheet1");
Row row = null;
// 获取样式
CellStyle headStyle = PoiUtils.getHeadStyle(workBook);
CellStyle tblTitleStyle = PoiUtils.getTblTitleCellStyle(workBook);
CellStyle cellStyle = PoiUtils.getTblCellStyle(workBook);
CellStyle cellIntStyle = PoiUtils.getTblCellStyle_INT(workBook);
// 设置默认行高
sheet.setDefaultRowHeightInPoints(20);
// 设置默认列宽
sheet.setDefaultColumnWidth(10);
// 设置特定单元格的宽度
// 设置“序号”的宽度
sheet.setColumnWidth(0, 4 * 256);
// sheet.setColumnWidth(1, 20 * 256);
// sheet.setColumnWidth(2, 30 * 256);
// 创建主标题
CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, fieldName.length - 1);
sheet.addMergedRegion(titleRange);
// 创建新行
row = sheet.createRow(rowNum);
// 设置行高
row.setHeightInPoints(24);
Cell cell = row.createCell(0);
cell.setCellValue("职称 列表");
cell.setCellStyle(headStyle);
// 创建副标题
// 创建列表题头信息
// 创建新行,遵循规则“看前不看后,后者自己补齐相关数据”
rowNum++;
row = sheet.createRow(rowNum);
// 设置行高
row.setHeightInPoints(24);
// 设置列表题头及样式
for (int cellitem = 0; cellitem < fieldName.length; cellitem++) {
cell = row.createCell(cellitem);
cell.setCellValue(fieldName[cellitem]);
cell.setCellStyle(tblTitleStyle);
}
// 创建列表信息
for (int item = 0; item < objList.size(); item++) {
KqTechnical bean = objList.get(item);
cellNum = 0;
// 创建新行
// 创建新行,遵循规则“看前不看后,后者自己补齐相关数据”
rowNum++;
row = sheet.createRow(rowNum);
// 设置行高
row.setHeightInPoints(24);
// 设置序号
cell = row.createCell(cellNum);
cell.setCellValue(item + 1);
cell.setCellStyle(cellIntStyle);
// 职称名称
// 创建新列,遵循规则“看前不看后,后者自己补齐相关数据”
cellNum++;
cell = row.createCell(cellNum);
cell.setCellValue(bean.getTechnicalName());
cell.setCellStyle(cellStyle);
// 备注
// 创建新列,遵循规则“看前不看后,后者自己补齐相关数据”
cellNum++;
cell = row.createCell(cellNum);
cell.setCellValue(bean.getMemo());
cell.setCellStyle(cellStyle);
}
// 设置标题:
// 将第一行作为标题,即每页都打印此行
CellRangeAddress repeatRange = new CellRangeAddress(0, 1, 0, fieldName.length - 1);
sheet.setRepeatingColumns(repeatRange);
// 页脚:
Footer footer = sheet.getFooter();
footer.setRight("第" + HSSFFooter.page() + "页 共" + HSSFFooter.numPages() + "页 ");
// 设置活动sheet为第一个
workBook.setActiveSheet(0);
// 输出到页面
// response.setContentType("text/html;charset=GBK");
response.setContentType("application/vnd.ms-excel");
response.addHeader("Content-Disposition", "attachment;filename=" + saveFileName + ".xls");
OutputStream out = response.getOutputStream();
workBook.write(out);
out.close();
} catch (IndexOutOfBoundsException ex) {
ex.printStackTrace();
}
}
}
其中KqTechnical为一个简单的bean,如下:
// 主键id
private int technicalId = 0;
// 职称名称
private String technicalName = "";
// 备注
private String memo = "";
PoiUtils中定义了POI对Excel的一些操作方法,如页拷贝、行拷贝、单元格拷贝(均含样式一起拷贝)、读取Excel文件到data[][]数组等方法,上述代码中仅简单使用了自定义样式,代码片段如下:
/**
* 创建主标题样式
*
* @param workbook
* @return
*/
public static CellStyle getHeadStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 设置水平居中
style.setAlignment(HorizontalAlignment.CENTER);
// 设置垂直居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
// 注:前景色与背景色均需要有,否则匹配后的背景颜色很怪异
// 设置前景色
style.setFillForegroundColor(IndexedColors.WHITE.getIndex());
// 设置背景色
style.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
// 设置填充模式
style.setFillPattern(FillPatternType.NO_FILL);
// 设置边框线型(无边框)
style.setBorderBottom(BorderStyle.NONE);
style.setBorderLeft(BorderStyle.NONE);
style.setBorderRight(BorderStyle.NONE);
style.setBorderTop(BorderStyle.NONE);
// 设置边框颜色
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
// 自动换行
style.setWrapText(true);
// 生成一个字体
Font font = workbook.createFont();
// 字体高度
font.setFontHeightInPoints((short) 14);
// 字体颜色
font.setColor(IndexedColors.BLACK.getIndex());
// 设置字体加粗
font.setBold(true);
// 字体
font.setFontName("宋体");
// 把字体 应用到当前样式
style.setFont(font);
return style;
}
3、 相关JAR包更新
需下载最新的jackson包,这里使用的是如下三个:
jackson-annotations-2.8.8.jar
jackson-core-2.8.8.jar
jackson-databind-2.8.8.jar