Java 文件流csv转xlsx工具类@杨章隐

最近跟进了一个导入文档的项目

但是在导入csv的时候突然报错了

Your InputStream was neither an OLE2 stream, nor an OOXML stream

Your InputStream was neither an OLE2 stream, nor an OOXML stream

这是因为POi不处理非excel类型文件,如果不是excel类型文件或者不是二进制类型文件直接就抛出异常"Your InputStream was neither an OLE2 stream, nor an OOXML stream"

这里提供一个工具类给大家处理解决这个问题

  1. maven依赖

<dependency>
    <groupId>org.jumpmind.symmetric</groupId>
    <artifactId>symmetric</artifactId>
    <version>2.0.15</version>
</dependency>

  1. 工具类代码


import cn.hutool.core.util.ObjectUtil;
import com.csvreader.CsvReader;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * Csv 转 Xlsx 工具类
 */
@Log4j2
public class XlsxUtil {
    /**
     * CSV常用分隔符,如需动态扩展设置成配置项
     */
    private static final char[] DELIMITERS = {
            ',',
            ';',
            '\001',
            ' ',
            '\t',
            '|',
            '#',
            '&'
    };

    /**
     * 读取CSV文件并写入到XLSX文件中,默认编码
     *
     * @param csvFileAddress 文件地址
     */
    public static String csvToXlsx(String csvFileAddress) {
        return csvToXlsx(csvFileAddress, "UTF-8");
    }

    /**
     * @param inputStream 输入流
     */
    public static InputStream csv2xlsx(InputStream inputStream, String fileName) {
        return csvStream2xlsxStream(inputStream, fileName);
    }

    /**
     * 读取CSV文件并写入到XLSX文件中,指定CSV文件编码
     *
     * @param csvFileAddress 文件地址
     * @param charset        编码
     */
    public static String csvToXlsx(String csvFileAddress, String charset) {
        String xlsxFileAddress = "";
        FileOutputStream fileOutputStream = null;
        try {
            char delimiter = getDelimiter(csvFileAddress);
            //xlsx file address
            xlsxFileAddress = csvFileAddress.replace("csv", "xlsx");
            XSSFWorkbook workBook = new XSSFWorkbook();
            XSSFSheet sheet = workBook.createSheet(getSheetName(csvFileAddress));
            int rowNum = -1;
            CsvReader csvReader = new CsvReader(csvFileAddress, delimiter, Charset.forName(charset));
            while (csvReader.readRecord()) {
                rowNum++;
                XSSFRow currentRow = sheet.createRow(rowNum);
                for (int i = 0; i < csvReader.getColumnCount(); i++) {
                    currentRow.createCell(i).setCellValue(csvReader.get(i));
                }
            }
            fileOutputStream = new FileOutputStream(xlsxFileAddress);
            workBook.write(fileOutputStream);
            return getFileName(xlsxFileAddress);
        } catch (Exception e) {
            log.error("CsvToXlsxUtil exception :", e);
        } finally {
            try {
                assert fileOutputStream != null;
                fileOutputStream.close();
            } catch (IOException e) {
                log.error("CsvToXlsxUtil close FileOutputStream exception :", e);
            }
        }
        return getFileName(xlsxFileAddress);
    }

    /**
     * @param inputStream 输入流
     */
    public static InputStream csvStream2xlsxStream(InputStream inputStream, String fileName) {
        FileOutputStream fileOutputStream = null;
        try {
            fileName = fileName.replace(".csv", ".xlsx");
            XSSFWorkbook workBook = new XSSFWorkbook();
            XSSFSheet sheet = workBook.createSheet("sheet1");
            int rowNum = -1;
            CsvReader csvReader = new CsvReader(inputStream, StandardCharsets.UTF_8);
            while (csvReader.readRecord()) {
                rowNum++;
                XSSFRow currentRow = sheet.createRow(rowNum);
                for (int i = 0; i < csvReader.getColumnCount(); i++) {
                    currentRow.createCell(i).setCellValue(csvReader.get(i));
                }
            }
            File file = new File("/" + fileName);
            fileOutputStream = new FileOutputStream(file);
            workBook.write(fileOutputStream);
            InputStream input = new FileInputStream(file);
            file.delete();
            return input;
        } catch (Exception e) {
            log.error("CsvToXlsxUtil exception :", e);
        } finally {
            try {
                if (ObjectUtil.isNotNull(fileOutputStream)) {
                    assert fileOutputStream != null;
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                log.error("CsvToXlsxUtil close FileOutputStream exception :", e);
            }
        }
        return null;
    }

    /**
     * 设置excel文件的sheet名称
     * 获取CSV文件名作为Excel文件的sheet名称
     *
     * @param path 资源路径
     */
    private static String getSheetName(String path) {
        try {
            String[] file = getFileName(path).split("\\.");
            return file[0];
        } catch (Exception e) {
            log.error("CsvToXlsxUtil get sheet name exception : ", e);
            return "Sheet";
        }
    }

    /**
     * 根据资源路径切割获取文件名
     *
     * @param path 资源路径
     */
    private static String getFileName(String path) {
        String[] paths = path.contains("\\") ? path.split("\\\\") : path.split("/");
        return paths[paths.length - 1];
    }

    /**
     * 常用CSV分隔符数组遍历资源第一行,分隔的字段数多的为资源分隔符
     * 异常情况下默认用’,‘作为分隔符
     *
     * @param path 资源路径
     */
    private static char getDelimiter(String path) {
        BufferedReader br = null;
        char delimiter = ',';
        try {
            br = new BufferedReader(new FileReader(path));
            String line = br.readLine();
            CsvReader csvReader;
            int columCount = 0;
            for (char delimiterTest : DELIMITERS) {
                csvReader = new CsvReader(getStringStream(line), delimiterTest, StandardCharsets.UTF_8);
                if (csvReader.readRecord()) {
                    int newColumnCount = csvReader.getColumnCount();
                    if (newColumnCount > columCount) {
                        columCount = newColumnCount;
                        delimiter = delimiterTest;
                    }
                }
            }
        } catch (Exception e) {
            log.error("CsvToXlsxUtil get delimiter exception :", e);
        } finally {
            try {
                assert br != null;
                br.close();
            } catch (IOException e) {
                log.error("CsvToXlsxUtil get delimiter close BufferedReader exception :", e);
            }
        }
        return delimiter;
    }

    /**
     * 字符串转输入流
     * 把CSV文件第一行数据转成输入流
     *
     * @param sInputString 字符串
     */
    private static InputStream getStringStream(String sInputString) {
        if (null != sInputString && !"".equals(sInputString)) {
            try {
                return new ByteArrayInputStream(sInputString.getBytes());
            } catch (Exception e) {
                log.error("CsvToXlsxUtil get StringStream exception :", e);
            }
        }
        return null;
    }
}

好了,这样之后你可以先转成合适的格式在进行导入数据等操作

### 回答1: Android 中有很多库和工具可以帮助实现 CSV 化为 XLSX 的功能。以下是一种可能的工具类实现: ```java import android.content.Context; import android.os.Environment; import android.util.Log; import com.opencsv.CSVReader; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; public class CSVtoXLSXConverter { private static final String TAG = "CSVtoXLSXConverter"; public static void convert(Context context, String csvFilePath, String xlsxFilePath) { try { FileInputStream fis = new FileInputStream(csvFilePath); InputStreamReader isr = new InputStreamReader(fis); CSVReader csvReader = new CSVReader(isr); XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet("Sheet1"); String[] nextLine; int rowNum = 0; while ((nextLine = csvReader.readNext()) != null) { Row row = sheet.createRow(rowNum++); for (int i = 0; i < nextLine.length; i++) { Cell cell = row.createCell(i); cell.setCellValue(nextLine[i]); } } csvReader.close(); File outputFile = new File(xlsxFilePath); FileOutputStream fos = new FileOutputStream(outputFile); workbook.write(fos); workbook.close(); fos.close(); } catch (IOException e) { Log.e(TAG, "Error converting CSV to XLSX: " + e.getMessage()); e.printStackTrace(); } } } ``` 上面的工具类使用了 Apache POI 和 OpenCSV 两个库来读取 CSV 文件并创建 XLSX 文件。在 `convert` 方法中,首先打开 CSV 文件并创建一个 CSVReader 实例,然后创建一个 XSSFWorkbook 实例用于保存 XLSX 数据。然后,通过遍历读取 CSV 的每一行,并将数据移到 XLSX 工作表中。最后,将生成的 XSSFWorkbook 写入到指定的 XLSX 文件中。 使用方法如下: ```java String csvFilePath = "/path/to/input.csv"; String xlsxFilePath = "/path/to/output.xlsx"; CSVtoXLSXConverter.convert(context, csvFilePath, xlsxFilePath); ``` 需要确保 Android 项目中已添加相应的依赖库。 ### 回答2: Android是一种基于Linux的移动操作系统,而CSV(Comma-Separated Values)是一种常见的文本文件格式,用于存储表格数据。而XLSX是一种Microsoft Excel文件格式,用于存储电子表格数据。因此,我们可能需要将CSV文件换为XLSX文件以便在Android设备上使用。 在Android中,我们可以使用Apache POI库来完成CSVXLSX换。Apache POI是一个用于操作Microsoft Office文件的开源库,它提供了许多功能丰富的API来读取、写入和操作不同格式的Office文件。 要使用Apache POI将CSV文件换为XLSX文件,首先需要添加Apache POI库的依赖到项目中。然后,我们可以使用以下步骤进行换: 1. 创建一个XSSFWorkbook对象,该对象表示整个Excel文件。 2. 创建一个XSSFSheet对象,该对象表示Excel文件中的一个工作表。 3. 使用CSVReader或BufferedReader从CSV文件中读取数据,并将其逐行存储到一个List或数组中。 4. 使用XSSFRow和XSSFCell对象在XSSFSheet中创建表格行和单元格,并将CSV数据写入XLSX文件。 5. 最后,使用FileOutputStream将XSSFWorkbook保存为XLSX文件。 这只是一个简单的示例,实际实现可能需要根据具体需求进行调整和修改。在实际应用中,我们可能还需要处理日期、数字格式、合并单元格等其他特殊情况。 总结起来,通过使用Apache POI库,我们可以在Android中编写一个工具类来实现CSVXLSX换。这个工具类可以帮助我们简便地读取CSV文件,并将其换为XLSX文件,以便在Android设备中方便地处理和展示表格数据。 ### 回答3: Android CSVXLSX工具类的主要功能是将CSV文件换为XLSX格式的Excel文件。它可以将CSV文件中的数据逐行解析并写入XLSX文件中的对应单元格。 首先,我们需要在Android项目中引入Apache POI库,它是一个用于操作Office文档的Java库。可以在build.gradle文件中添加以下依赖: implementation 'org.apache.poi:poi:4.1.2' implementation 'org.apache.poi:poi-ooxml:4.1.2' 然后,我们可以创建一个Converter类,其中包含一个静态方法csvToXlsx(),接受CSV文件路径和输出XLSX文件路径作为参数。 在该方法内部,我们首先创建一个XSSFWorkbook对象,它表示Excel文件,并创建一个XSSFSheet对象,表示工作表。 接下来,我们需要读取CSV文件中的数据。我们可以使用BufferedReader和FileReader来逐行读取CSV文件,并使用String的split()方法分隔逗号或其他分隔符分隔的值。 然后,我们需要使用XSSFRow和XSSFCell来创建行和单元格。我们可以使用forEach循环迭代CSV文件中的每一行,并将每个值写入对应的单元格。 最后,我们使用FileOutputStream将XSSFWorkbook对象写入XLSX文件中,并关闭工作簿和输出。 以下是一个简单的Android CSVXLSX工具类的示例: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.FileReader; public class Converter { public static void csvToXlsx(String csvFilePath, String xlsxFilePath) throws Exception { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Sheet1"); BufferedReader bufferedReader = new BufferedReader(new FileReader(csvFilePath)); String line; int rowIdx = 0; while ((line = bufferedReader.readLine()) != null) { String[] data = line.split(","); Row row = sheet.createRow(rowIdx++); int cellIdx = 0; for (String value : data) { Cell cell = row.createCell(cellIdx++); cell.setCellValue(value); } } bufferedReader.close(); FileOutputStream fileOutputStream = new FileOutputStream(xlsxFilePath); workbook.write(fileOutputStream); fileOutputStream.close(); workbook.close(); } } ``` 使用这个工具类,我们可以很容易地将CSV文件化为XLSX格式的Excel文件。只需要调用Converter.csvToXlsx()方法,并提供要换的CSV文件路径和要输出的XLSX文件路径即可。 注意:在使用这个工具类之前,确保已经在Android项目中导入了正确的POI库。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨章隐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值