在Java中将.csv文件转换为.xls文件

16

有谁知道在Java中将csv文件快速、清晰地转换为xls或xlsx文件的方法吗?

我已经有了一些管理csv文件的方法,但我需要更多的兼容性以供其他程序使用。

除了包名之外,如果能提供示例代码就更好了。

非常感谢,

Justian

以下是我迄今为止的代码。我需要从行中删除换行符("\n")。我的某些单元格包含多行信息(列表),因此我可以在csv中使用"\n"来表示单元格内的多行信息,但xls会将这些视为我要将它们放在新的上。

这段代码改编自网络,目前有点凌乱。你可能会注意到一些已弃用的方法,因为它是2004年编写的,请忽略可怕的返回语句。我现在只是用S.o.p进行测试,稍后会整理它们。

package jab.jm.io;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class FileConverter {

    public static String ConvertCSVToXLS(String file) throws IOException {

        if (file.indexOf(".csv") < 0)
            return "Error converting file: .csv file not given.";

        String name = FileManager.getFileNameFromPath(file, false);
        ArrayList<ArrayList<String>> arList = new ArrayList<ArrayList<String>>();
        ArrayList<String> al = null;

        String thisLine;
        DataInputStream myInput = new DataInputStream(new FileInputStream(file));

        while ((thisLine = myInput.readLine()) != null) {
            al = new ArrayList<String>();
            String strar[] = thisLine.split(",");

            for (int j = 0; j < strar.length; j++) {
                // My Attempt (BELOW)
                String edit = strar[j].replace('\n', ' ');
                al.add(edit);
            }

            arList.add(al);
            System.out.println();
        }

        try {
            HSSFWorkbook hwb = new HSSFWorkbook();
            HSSFSheet sheet = hwb.createSheet("new sheet");

            for (int k = 0; k < arList.size(); k++) {
                ArrayList<String> ardata = (ArrayList<String>) arList.get(k);
                HSSFRow row = sheet.createRow((short) 0 + k);

                for (int p = 0; p < ardata.size(); p++) {
                    System.out.print(ardata.get(p));
                    HSSFCell cell = row.createCell((short) p);
                    cell.setCellValue(ardata.get(p).toString());
                }
            }

            FileOutputStream fileOut = new FileOutputStream(
                    FileManager.getCleanPath() + "/converted files/" + name
                            + ".xls");
            hwb.write(fileOut);
            fileOut.close();

            System.out.println(name + ".xls has been generated");
        } catch (Exception ex) {
        }

        return "";
    }
}

我的回答已更新。抱歉让你等了一会儿。 - Carl Smotricz
6个回答

9

复制以下程序,我运行了这个程序,它可以正常工作。如果您对此程序有任何疑虑,请告诉我。(您需要Apache POI Jar才能运行此程序)

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;


public class CSVToExcelConverter {

    public static void main(String args[]) throws IOException
    {
        ArrayList arList=null;
        ArrayList al=null;
        String fName = "test.csv";
        String thisLine;
        int count=0;
        FileInputStream fis = new FileInputStream(fName);
        DataInputStream myInput = new DataInputStream(fis);
        int i=0;
        arList = new ArrayList();
        while ((thisLine = myInput.readLine()) != null)
        {
            al = new ArrayList();
            String strar[] = thisLine.split(",");
            for(int j=0;j<strar.length;j++)
            {
                al.add(strar[j]);
            }
            arList.add(al);
            System.out.println();
            i++;
        }

        try
        {
            HSSFWorkbook hwb = new HSSFWorkbook();
            HSSFSheet sheet = hwb.createSheet("new sheet");
            for(int k=0;k<arList.size();k++)
            {
                ArrayList ardata = (ArrayList)arList.get(k);
                HSSFRow row = sheet.createRow((short) 0+k);
                for(int p=0;p<ardata.size();p++)
                {
                    HSSFCell cell = row.createCell((short) p);
                    String data = ardata.get(p).toString();
                    if(data.startsWith("=")){
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        data=data.replaceAll("\"", "");
                        data=data.replaceAll("=", "");
                        cell.setCellValue(data);
                    }else if(data.startsWith("\"")){
                        data=data.replaceAll("\"", "");
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        cell.setCellValue(data);
                    }else{
                        data=data.replaceAll("\"", "");
                        cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                        cell.setCellValue(data);
                    }
                    //*/
                    // cell.setCellValue(ardata.get(p).toString());
                }
                System.out.println();
            }
            FileOutputStream fileOut = new FileOutputStream("test.xls");
            hwb.write(fileOut);
            fileOut.close();
            System.out.println("Your excel file has been generated");
        } catch ( Exception ex ) {
            ex.printStackTrace();
        } //main method ends
    }
}

9

不知道你是否已经知道了,但是:

  • Excel(如果这是你的真正目标)可以轻松直接读取.csv文件,因此任何转换都只是为了让你不那么“聪明”的用户更方便。
  • CSV是一个最低公共分母格式。任何转换器都不太可能添加到.csv文件中找到的信息,使其更有用。换句话说,CSV是一种“愚蠢”的格式,将其转换为.xls将(可能)增加文件大小,但不会使格式更聪明。

Curtis建议使用POI也是我首先想到的。

如果您在Windows计算机上进行此转换,另一种选择可能是Jacob,这是一个Java-COM桥,允许您有效地从Java程序远程控制Excel,以便执行诸如打开文件并以不同格式保存等操作,甚至应用一些格式更改或类似操作。

最后,我还成功地通过JDBC将SQL INSERT插入到通过JDBC-ODBC桥接访问的Excel工作表中。也就是说,ODBC可以使Excel文件看起来像数据库。不过它并不是非常灵活,您不能要求DB创建任意命名的.XLS文件。


编辑:

在我看来,readLine()已经无法给你整行了。它怎么知道回车符不是行终止符?您应该能够通过在readLine()之后立即使用调试打印语句来验证这一点。

如果确实如此,那么就很糟糕了,因为前进的方法是:

  • 或者识别不完整的行并在事后将它们粘合在一起,
  • 或者编写自己的readLine()替代品。一个简单的方法是逐个字符地读取,在CSV字符串中替换CR,并在StringBuilder中累积文本,直到您感觉到有一个完整的行。

这两种替代方案都可能是您不希望面对的工作。


好的,我正在使用从一个网站(我无法控制)中拉取的数据,并且他们以csv格式导出这些数据。不幸的是,我想要使用数据的一些程序需要xls文件。是的,“向上转换”是毫无意义的,但这是我必须使用的软件问题。我一直在尝试POI,并取得了一些成功,但它似乎讨厌回车符(\n),而我之前可以在CSV中使用它们(可以理解,因为逗号是分隔符)。我将在上面发布我的代码。有什么办法可以去除这些字符吗?请看上面我所尝试的方法。 - Justian Meyer
@Justian:浏览了你的代码,我无法确定你试图解决的问题是什么。这些CR是否在字段中间还是记录末尾?如果它们在字段中,是否应该用一个空格替换它们?你的代码没有成功吗? - Carl Smotricz
不,不是这样的。假设我有一个包括姓名 | 宠物 | 邮政编码字段的表格。如果CSV中存在多行列,例如“john | dog (\n) cat | 10000”,它将显示为“john | dog”和(下一行)“cat | zip”。用stackoverflow的自动格式很难展示这个问题。据我所见,它应该可以进行修正,但目前还没有成功。 - Justian Meyer
如果您编写包含十六进制0E00的CSV数据,Excel通常会“帮助”将其转换为数字。您可以通过一些CSV导入的技巧来解决这个问题,但这会给最终用户带来很多麻烦,因此我们宁愿自己处理Excel创建,以确保列不会自动转换。 - cyber-monk

8
如果你想在Java中读取或写入XLS或XLSX文件,Apache POI是一个不错的选择: http://poi.apache.org/

3

Excel中的工具不足以满足OP想要做的事情。他在这方面走对了路。Excel无法将多个CSV文件导入到同一文件的不同工作表中,因此您需要在代码中执行此操作。我的建议是使用OpenCSV读取CSV,因为它可以自动纠正数据中的换行符和缺失列,并且它是免费和开源的。它实际上非常强大,可以处理各种不同的非标准CSV文件。


0
你写道:

我已经有了一些管理 CSV 文件的工具,但我需要额外的兼容性以适应其他程序。

那些其他程序是什么?它们是否需要通过 Excel 文件访问您的数据,或者可以通过 JDBC 或 ODBC 连接到数据库进行工作?使用数据库作为中心位置,您可以根据需要将数据提取到 CSV 文件或其他格式中。


0

我创建了一个名为csv2xls的小型软件。它需要Java。


谢谢@Jaan。现在,它在这里:(https://github.com/sixro/incubateur/tree/master/csv2xls)。 - Sixro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接