import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import org.apache.log4j.Logger; import de.schlichtherle.io.ArchiveDetector; import de.schlichtherle.io.DefaultArchiveDetector; import de.schlichtherle.io.File; import de.schlichtherle.io.FileInputStream; import de.schlichtherle.io.FileOutputStream; public class OpenOfficeXlsxRepair { private static final Logger log = Logger.getLogger(OpenOfficeXlsxRepair.class); public OpenOfficeXlsxRepair() { super(); File.setDefaultArchiveDetector(new DefaultArchiveDetector(ArchiveDetector.NULL, new String[] { "xlsx", "de.schlichtherle.io.archive.zip.Zip32Driver" })); } public void repairFile(String xlsxFilePath) { StringBuilder sb = new StringBuilder(); boolean changesRequired = readRelsFile(xlsxFilePath, sb); if (changesRequired) { writeRelsFile(xlsxFilePath, sb); } } private void writeRelsFile(String xlsxFilePath, StringBuilder sb) { log.debug("Fixing xlsx file for OpenOffice: " + xlsxFilePath); File xlsxFile = new File(xlsxFilePath); File relsFile = new File(xlsxFile, "_rels/.rels"); OutputStream output = null; try { output = new FileOutputStream(relsFile); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output)); writer.write(sb.toString()); writer.flush(); } catch (Throwable e) { log.error("Error updating for OpenOffice: " + xlsxFilePath, e); throw new RuntimeException("Error updating for OpenOffice: " + xlsxFilePath, e); } finally { if (output != null) { try { output.close(); File.update(xlsxFile, true); } catch (IOException e) { } } } } private boolean readRelsFile(String xlsxFilePath, StringBuilder sb) { File relsFile = new File(xlsxFilePath, "_rels/.rels"); InputStream workbookInputStream = null; boolean changesRequired = false; try { workbookInputStream = new FileInputStream(relsFile); BufferedReader br = new BufferedReader(new InputStreamReader(workbookInputStream)); String line = null; while ((line = br.readLine()) != null) { // Remove the leading slashes from /xl/workbook entries for // compatibility // with OpenOffice if (line.indexOf("Target=\"/") >= 0) { line = line.replaceAll("Target=\"/", "Target=\""); changesRequired = true; } sb.append(line); sb.append("\n"); } } catch (Throwable e) { log.error("Error updating for OpenOffice: " + xlsxFilePath, e); throw new RuntimeException("Error updating for OpenOffice: " + xlsxFilePath, e); } finally { if (workbookInputStream != null) { try { workbookInputStream.close(); } catch (IOException e) { } } } return changesRequired; } }