【问题标题】:XLSX file getting corrupted when trying to write data into multiple sheets in JAVA尝试在 JAVA 中将数据写入多张工作表时,XLSX 文件损坏
【发布时间】:2014-04-25 16:41:58
【问题描述】:

我是 JAVA 新手。我需要将特定文件夹中的多个文件加载到 excel xlsx(不是 xls 文件,因为输入文件有超过 65k 条记录)文件不同的工作表。下面是我写的代码。 xlsx 文件已损坏,无法打开。你能帮忙吗?

      public class twotxttoxlsx{
             public static void main(String[]args){
             try{

               File folder = new File("C:/txttoxls/");
            File[] listOfFiles = folder.listFiles();
                  XSSFWorkbook workbook=new XSSFWorkbook();

            for (File file : listOfFiles) {


   if (file.isFile()) {

       String thisline;
       ArrayList<String> al = null;
       ArrayList<ArrayList<String>> arlist = new ArrayList<ArrayList<String>>();

       XSSFSheet sheet =  workbook.createSheet(file.getName());  
           FileInputStream fis = new FileInputStream(file);
           System.out.println("Got here");
           BufferedReader br = new BufferedReader(new InputStreamReader(fis));

           while ((thisline = br.readLine()) != null) {
               al = new ArrayList<String>();
               String strar[] = thisline.split("#");

               for (int j = 0; j < strar.length; j++) { 
                   for (int k = 0; k < arlist.size(); k++) {

                       ArrayList<String> ardata = (ArrayList<String>) arlist.get(k);

                       XSSFRow row = sheet.createRow((short) k);


                       for (int p = 0; p < ardata.size(); p++) {

                           XSSFCell cell = row.createCell((short) p);
                           cell.setCellValue(ardata.get(p).toString());

                       }
                   }

                   al.add(strar[j]);

               } 

             arlist.add(al);
           }

           fis.close();  
           FileOutputStream fileOut = new FileOutputStream("C:/txttoxls/Test.xlsx");
           workbook.write(fileOut);
           fileOut.flush();
           fileOut.close();
           br.close();
   }
   }

           System.out.println("Your excel file has been generated!");

            } catch ( Exception ex ) {
                 System.out.println(ex);

                }
                }
  }

4/27 编辑:工作代码但存在性能问题。

 import java.io.*;
 import java.util.ArrayList; 
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.poi.xssf.usermodel.XSSFRow;
 import org.apache.poi.xssf.usermodel.XSSFCell;


public class createXLSXfileTest{
public static void main(String[]args){

    XSSFWorkbook workbook=new XSSFWorkbook();
    XSSFSheet sheet = (XSSFSheet) workbook.createSheet("sheet1");  
    XSSFSheet sheet1 = (XSSFSheet) workbook.createSheet("Sheet2");
    try{

           File file = new File("C:/Users/Desktop/file1.txt");

          FileOutputStream fileOut = new FileOutputStream("C:/Users/Desktop/test.xlsx");

      if (file.isFile()) {

       String thisline;
       ArrayList<String> al = null;
       ArrayList<ArrayList<String>> arlist = new ArrayList<ArrayList<String>>();


           FileInputStream fis = new FileInputStream(file);
           System.out.println("loading 1st file");
           BufferedReader br = new BufferedReader(new InputStreamReader(fis));

           while ((thisline = br.readLine()) != null) {
               al = new ArrayList<String>();
               String strar[] = thisline.split("#");

               for (int j = 0; j < strar.length; j++) { 
                   for (int k = 0; k < arlist.size(); k++) {

                       ArrayList<String> ardata = (ArrayList<String>) arlist.get(k);

                       XSSFRow row = sheet.createRow((short) k);


                       for (int p = 0; p < ardata.size(); p++) {

                           XSSFCell cell = row.createCell((short) p);
                           cell.setCellValue(ardata.get(p).toString());

                       }
                   }

                   al.add(strar[j]);

               } 

             arlist.add(al);
           }

           fis.close();  

      }
      File file1 = new File("C:/Users/Desktop/file2.txt");
      if (file1.isFile()) {

          String thisline;
          ArrayList<String> al = null;
          ArrayList<ArrayList<String>> arlist = new ArrayList<ArrayList<String>>();


              FileInputStream fis = new FileInputStream(file1);
              System.out.println("loading 2nd file");
              BufferedReader br = new BufferedReader(new InputStreamReader(fis));

              while ((thisline = br.readLine()) != null) {
                  al = new ArrayList<String>();
                  String strar[] = thisline.split("#");

                  for (int j = 0; j < strar.length; j++) { 
                      for (int k = 0; k < arlist.size(); k++) {

                          ArrayList<String> ardata = (ArrayList<String>) arlist.get(k);

                          XSSFRow row = sheet1.createRow((short) k);


                          for (int p = 0; p < ardata.size(); p++) {

                              XSSFCell cell = row.createCell((short) p);
                              cell.setCellValue(ardata.get(p).toString());

                          }
                      }

                      al.add(strar[j]);

                  } 

                arlist.add(al);
              }

              fis.close();  
                             workbook.write(fileOut);
              fileOut.flush();
              fileOut.close();
              br.close();


      System.out.println("Your excel file has been generated!");


   }} catch ( Exception ex ) {
   System.out.println(ex);

  }

  }
 }

【问题讨论】:

  • 是否抛出了您未在此处显示的异常?
  • 不,我没有。它运行良好,没有任何错误,甚至生成文件。但它已损坏。如果我的输入文件夹中没有多个文件,这意味着使用一个输入文件可以毫无问题地创建 xlsx 文件。
  • 我想念workbook.close() 而不需要fileOut.flush 和close。
  • 您要在文件中总共存储多少行?你生成了多少个标签?生成的 XLSX 的最终大小是多少?当您为单个文件生成 xlsx 时它是否有效?它适用于2个文件吗?如果确实如此,则尝试在每次迭代FileOutputStream fileOut = new FileOutputStream("C:/txttoxls/Test" + introducedFileIndex + ".xlsx"); 时生成一个单独的 xlsx 文件 - 因为您每次都在添加工作表,您将能够看到它开始中断的位置。

标签: java excel apache-poi


【解决方案1】:

我唯一能看到的是您的工作表名称可能有问题。

XSSFSheet sheet = workbook.createSheet(file.getName());

Excel 工作表名称非常严格。最大长度为 31,并且不允许使用许多特殊字符,包括 /[]:\? 等等。考虑编写一个“toWorksheetName”函数将文件名清理为合法的工作表名称。

您可以尝试的另一件事是尝试使用 POI 读取 XLS。这可能有助于缩小问题的范围。 Help is here,在“使用 .xlsx 文件”下。

附带说明:您不需要关闭fis;关闭br 就足够了。 Close() 从装饰器传递到包装的流。不过这不会破坏任何东西。

【讨论】:

  • Excel 工作表名称非常严格。最大长度 31 听起来像是 4.30 AM 的经验发现,让你“啊!”。
  • 感谢您的回复。最后,我的代码可以为每个输入文件生成带有单独选项卡的 xlsx 文件。但是我的实际文件面临性能问题,因为其中一个输入文件有大约 30 万条记录。它永远在运行。你能帮我重写代码以提高性能吗?我已将工作代码添加到我的原始帖子中。
  • 这里有几个想法。 (1) 摆脱 arlist 并直接从 strar 读取每一行。这将节省大量内存和无意义的复制。 (2) 将 main 移到 createXLSXfile(String filename) 之类的方法中,然后在 5-10 左右的线程池中的不同线程上创建每个 XLSX 文件。这可能会加快 8 倍左右的速度。 (3) 使用 VBA 代替 Java。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多