xls转xlsx可用方法

该文章已生成可运行项目,

以下代码一般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);
    }
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值