以下代码一般xls转换没有什么问题,基于poi 3.15(项目版本比较老),如果使用新版本,可以做一些小的调整:
public static File convertXlsToXlsx2(File sourcefile) {
try (InputStream is = new FileInputStream(sourcefile);
Workbook inputWorkbook = new HSSFWorkbook(is);
Workbook outputWorkbook = new XSSFWorkbook()) {
// 复制所有工作表
for (int i = 0; i < inputWorkbook.getNumberOfSheets(); i++) {
Sheet inputSheet = inputWorkbook.getSheetAt(i);
Sheet outputSheet = outputWorkbook.createSheet(inputSheet.getSheetName());
copySheetWithStyles(inputSheet, outputSheet);
}
String outputPath = tempxlspath+sourcefile.getName()+"x";
// 保存转换后的文件
try (OutputStream os = new FileOutputStream(outputPath)) {
outputWorkbook.write(os);
}
System.out.println("转换成功: " + outputPath);
File tempFile = new File(outputPath);
if(tempFile.exists()){
return tempFile;
}
} catch (IOException e) {
System.err.println("转换失败: " + e.getMessage());
e.printStackTrace();
}
return null;
}
public static void copySheetWithStyles(Sheet sourceSheet, Sheet targetSheet) {
Workbook targetWorkbook = targetSheet.getWorkbook();
Workbook sourceWorkbook = sourceSheet.getWorkbook();
// 1. 复制列宽
for (int i = 0; i <= sourceSheet.getRow(0).getLastCellNum(); i++) {
int columnWidth = sourceSheet.getColumnWidth(i);
targetSheet.setColumnWidth(i, columnWidth);
// 复制列隐藏状态
if (sourceSheet.isColumnHidden(i)) {
targetSheet.setColumnHidden(i, true);
}
}
// 2. 复制行高
for (int i = 0; i <= sourceSheet.getLastRowNum(); i++) {
Row sourceRow = sourceSheet.getRow(i);
if (sourceRow != null) {
Row targetRow = targetSheet.createRow(i);
targetRow.setHeight(sourceRow.getHeight());
// 复制行隐藏状态
if (sourceRow.getZeroHeight()) {
targetRow.setZeroHeight(true);
}
}
}
// 3. 复制合并单元格区域
for (int i = 0; i < sourceSheet.getNumMergedRegions(); i++) {
CellRangeAddress mergedRegion = sourceSheet.getMergedRegion(i);
targetSheet.addMergedRegion(mergedRegion);
// 可选:复制合并区域的边框样式
copyMergedRegionBorders(sourceSheet, targetSheet, mergedRegion);
}
// 4. 复制单元格样式和内容
for (int rowNum = 0; rowNum <= sourceSheet.getLastRowNum(); rowNum++) {
Row sourceRow = sourceSheet.getRow(rowNum);
if (sourceRow == null) continue;
Row targetRow = targetSheet.getRow(rowNum);
if (targetRow == null) targetRow = targetSheet.createRow(rowNum);
for (int colNum = 0; colNum <= sourceRow.getLastCellNum(); colNum++) {
Cell sourceCell = sourceRow.getCell(colNum);
if (sourceCell == null) continue;
Cell targetCell = targetRow.createCell(colNum);
// 复制单元格值
copyCellValue(sourceCell, targetCell);
// 复制单元格样式
CellStyle sourceStyle = sourceCell.getCellStyle();
CellStyle targetStyle = targetWorkbook.createCellStyle();
copyCellStyle(sourceStyle, targetStyle, sourceWorkbook,targetWorkbook);
targetCell.setCellStyle(targetStyle);
}
}
}
// 复制单元格值
private static void copyCellValue(Cell source, Cell target) {
switch (source.getCellType()) {
case Cell.CELL_TYPE_STRING:
target.setCellValue(source.getStringCellValue());
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(source)) {
target.setCellValue(source.getDateCellValue());
} else {
target.setCellValue(source.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
target.setCellValue(source.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
target.setCellFormula(source.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK:
target.setCellValue("");
break;
default:
target.setCellValue(source.getStringCellValue());
}
}
private static void copyCellStyle(CellStyle sourceStyle, CellStyle targetStyle,Workbook sourceWorkbook, Workbook targetWorkbook) {
// 复制字体
Font sourceFont = sourceWorkbook.getFontAt(sourceStyle.getFontIndex());
Font targetFont = targetWorkbook.createFont();
copyFont(sourceFont, targetFont);
targetStyle.setFont(targetFont);
// 背景和填充
targetStyle.setFillBackgroundColor(sourceStyle.getFillBackgroundColor());
targetStyle.setFillForegroundColor(sourceStyle.getFillForegroundColor());
targetStyle.setFillPattern(sourceStyle.getFillPatternEnum());
// 边框
targetStyle.setBorderTop(sourceStyle.getBorderTopEnum());
targetStyle.setBorderBottom(sourceStyle.getBorderBottomEnum());
targetStyle.setBorderLeft(sourceStyle.getBorderLeftEnum());
targetStyle.setBorderRight(sourceStyle.getBorderRightEnum());
targetStyle.setTopBorderColor(sourceStyle.getTopBorderColor());
targetStyle.setBottomBorderColor(sourceStyle.getBottomBorderColor());
targetStyle.setLeftBorderColor(sourceStyle.getLeftBorderColor());
targetStyle.setRightBorderColor(sourceStyle.getRightBorderColor());
// 对齐方式
targetStyle.setAlignment(sourceStyle.getAlignmentEnum());
targetStyle.setVerticalAlignment(sourceStyle.getVerticalAlignmentEnum());
// 其他属性
targetStyle.setWrapText(sourceStyle.getWrapText());
targetStyle.setIndention(sourceStyle.getIndention());
targetStyle.setRotation(sourceStyle.getRotation());
targetStyle.setDataFormat(sourceStyle.getDataFormat());
targetStyle.setHidden(sourceStyle.getHidden());
targetStyle.setLocked(sourceStyle.getLocked());
targetStyle.setShrinkToFit(sourceStyle.getShrinkToFit());
// 安全处理quotePrefixed(版本兼容)
try {
Method getQuotePrefixed = CellStyle.class.getMethod("getQuotePrefixed");
Method setQuotePrefixed = CellStyle.class.getMethod("setQuotePrefixed", boolean.class);
boolean quoteValue = (Boolean) getQuotePrefixed.invoke(sourceStyle);
setQuotePrefixed.invoke(targetStyle, quoteValue);
} catch (Exception e) {
// 方法不存在则忽略
}
}
// 复制字体属性
private static void copyFont(Font source, Font target) {
target.setBold(source.getBold());
target.setItalic(source.getItalic());
target.setUnderline(source.getUnderline());
target.setFontHeight(source.getFontHeight());
target.setFontName(source.getFontName());
target.setColor(source.getColor());
target.setStrikeout(source.getStrikeout());
target.setTypeOffset(source.getTypeOffset());
target.setCharSet(source.getCharSet());
}
// 可选:复制合并区域的边框
private static void copyMergedRegionBorders(Sheet sourceSheet, Sheet targetSheet, CellRangeAddress region) {
// 获取源合并区域的边框样式
Cell sourceCell = sourceSheet.getRow(region.getFirstRow()).getCell(region.getFirstColumn());
if (sourceCell == null) return;
CellStyle sourceStyle = sourceCell.getCellStyle();
// 应用边框到目标合并区域
setBorderTop(sourceStyle.getBorderTop(), region, targetSheet);
setBorderBottom(sourceStyle.getBorderBottom(), region, targetSheet);
setBorderLeft(sourceStyle.getBorderLeft(), region, targetSheet);
setBorderRight(sourceStyle.getBorderRight(), region, targetSheet);
setTopBorderColor(sourceStyle.getTopBorderColor(), region, targetSheet);
setBottomBorderColor(sourceStyle.getBottomBorderColor(), region, targetSheet);
setLeftBorderColor(sourceStyle.getLeftBorderColor(), region, targetSheet);
setRightBorderColor(sourceStyle.getRightBorderColor(), region, targetSheet);
}

5146

被折叠的 条评论
为什么被折叠?



