0

I am trying to read in a text file, and then apply some data validations rules on it. After adding the rules I then write data back onto an excel file.

But when trying to write it back to the excel file I get this error:

Exception in thread "main" org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Fail to save: an error occurs while saving the package : The part /docProps/app.xml fail to be saved in the stream with marshaller org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller@74ad1f1f at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:479) at org.apache.poi.openxml4j.opc.OPCPackage.save(OPCPackage.java:1414) at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:179) at com.gbt.POC.TxtFileReader.main(TxtFileReader.java:359) Caused by: org.apache.poi.openxml4j.exceptions.OpenXML4JException: The part /docProps/app.xml fail to be saved in the stream with marshaller org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller@74ad1f1f at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:470) ... 3 more

Here is what I have so far:

LinkedList < String[] > llist = new LinkedList < > ();

String[] data;

XSSFWorkbook workBook = new XSSFWorkbook();
FileOutputStream outstream = new FileOutputStream("data.xls");
XSSFSheet spreadSheet = workBook.createSheet("Clean");

for (int i = 0; i < llist.size(); i++) {
 if (i == 0) {
  System.out.println("Hello World!");
 } else {
  data = llist.get(i);

  String empid1 = data[0];
  String fname = data[1];
  String ccode1 = data[2];

  if (data[2].equals("IND")) {
   replace = data[2].replaceAll("IND", "IN");
   ccode1 = replace;
  } else if (data[2].equals("USA")) {
   replace = data[2].replaceAll("USA", "US");
   ccode1 = replace;
  } else {
   ccode1 = data[2];
  }

  //String newData=empid1+","+fname+","+ccode1;

  XSSFRow row = spreadSheet.createRow(i);

  XSSFCell cell = row.createCell(0);
  cell.setCellValue(empid1);

  cell = row.createCell(1);
  cell.setCellValue(fname);

  cell = row.createCell(2);
  cell.setCellValue(ccode1);
 }
}

workBook.write(outstream);

Any help is appreciated in advance.

2 Answers 2

0

I copied and pasted your code to see what error is it. Unfortunately I couldn't see your error. But after searching the error I found some answers..

This exception occurred because the POI API for excel sheet writes to the excel sheet multiple times. And each time it requires a new instance of FileOutputStream over same File object.

To resolve this, wrote all Rows to the workbook instance first, and at one did write to the workbook using FileOutputStream.

https://tjavadeeps.wordpress.com/2015/04/14/org-apache-poi-openxml4j-exceptions-openxml4jruntimeexception-fail-to-save-an-error-occurs-while-saving-the-package/

org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Fail to save

Hope you get a hint.

Next, I made my txt file and save to excel like what you did and It works,

package excelTest;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class readExcel {

    public static void main(String[] args) throws IOException {
        LinkedList<String> llist = new LinkedList<>();
        String[] data = null;
        String replace = "";
        XSSFWorkbook workBook = new XSSFWorkbook();
        FileOutputStream outstream = new FileOutputStream( "C:\\Users\\Desktop\\data.xls");
        XSSFSheet spreadSheet = workBook.createSheet("Clean");

        /*
         * MyFile.txt
           ----------------------
            0
            IND 
            USA
            LOVE
           ----------------------
         */



        try (BufferedReader br = new BufferedReader(new FileReader( "C:\\Users\\Desktop\\myFile.txt"))) {
            String sCurrentLine;

            while ((sCurrentLine = br.readLine()) != null) {
                llist.add(sCurrentLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


        String empid1 = "";
        String fname = "";
        String ccode1 = "";


        System.out.println("llist.get(i)"+llist.get(0)+"   "+llist.get(1));
        for (int i = 0; i < llist.size(); i++){
            System.out.println(llist.get(i));
        }
        empid1 = llist.get(1);  //IND
        fname = llist.get(2);   //USA
        ccode1 =llist.get(3);   //LOVE


        if (fname.equals("IND")) {
            replace = fname.replaceAll("IND", "IN");
            ccode1 = replace;
        } else if (fname.equals("USA")) {
            replace = fname.replaceAll("USA", "US");
            ccode1 = replace; //'LOVE' CHANGE TO US. (IF YOU WANT TO CHANGE TO US IN HERE-> fname=fname.replaceAll("USA","US");
        } else {
            ccode1 = fname; //'LOVE' CHANGE TO USA AGAIN.
        }


        XSSFRow row = spreadSheet.createRow(0);

        XSSFCell cell = row.createCell(0);
        cell.setCellValue(empid1);

        cell = row.createCell(1);
        cell.setCellValue(fname);

        cell = row.createCell(2);
        cell.setCellValue(ccode1);
        workBook.write(outstream);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

-1

You could use the Xcelite library to make your life easier:

  1. First create a little bean class

  2. Create a Xcelite object and have it create a sheet

  3. Get a Writer

  4. Write you beans

  5. Write to OutputStream

Bean class

import com.ebay.xcelite.annotations.Column;

public class Entity {
    @Column
    String empid1;
    @Column
    String fname;
    @Column
    String ccode1;
}

Create a Xcelite object and have it create a Sheet and a Writer

Xcelite xcelite = new Xcelite();
XceliteSheet sheet = xcelite.createSheet("Clean");
SheetWriter writer = sheet.getBeanWriter(Entity.class);

Write out

    writer.write(entities);
    xcelite.write(outstream);

To sum it up, here is your modified code:

    LinkedList<String[]> llist = new LinkedList <> ();
    String in0[] = new String[3];
    llist.add(in0);
    String in1[] = new String[3];
    in1[0] = "1";
    in1[1] = "testtest";
    in1[2] = "IND";
    llist.add(in1);

    String[] data;
    FileOutputStream outstream = new FileOutputStream( "C:\\Users\\Desktop\\data.xls");
    Xcelite xcelite = new Xcelite();
    XceliteSheet sheet = xcelite.createSheet("Clean");
    SheetWriter writer = sheet.getBeanWriter(Entity.class);
    List<Entity> entities = new ArrayList<>();

    for (int i = 0; i < llist.size(); i++) {
        if (i == 0) {
            System.out.println("Hello World!");
        } else {
            data = llist.get(i);
            String ccode1 = data[2];

            String replace;
            if (data[2].equals("IND")) {
                replace = data[2].replaceAll("IND", "IN");
                ccode1 = replace;
            } else if (data[2].equals("USA")) {
                replace = data[2].replaceAll("USA", "US");
                ccode1 = replace;
            } else {
                ccode1 = data[2];
            }
            Entity entity = new Entity();
            entities.add(entity);
            entity.empid1 = data[0];
            entity.fname = data[1];
            entity.ccode1 = ccode1;
        }
    }
    writer.write(entities);
    xcelite.write(outstream);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.