org.openl.rules.webstudio.util.XSSFOptimizer Maven / Gradle / Ivy
package org.openl.rules.webstudio.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyle;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellStyles;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class XSSFOptimizer {
private static final Logger LOG = LoggerFactory.getLogger(XSSFOptimizer.class);
public static void removeUnusedStyles(XSSFWorkbook workbook) {
LOG.info("Starting style optimization...");
try {
StylesTable stylesSource = workbook.getStylesSource();
@SuppressWarnings("unchecked")
List xfs = (List) FieldUtils.readDeclaredField(stylesSource, "xfs", true);
@SuppressWarnings("unchecked")
List styleXfs = (List) FieldUtils.readDeclaredField(stylesSource, "styleXfs", true);
CTCellStyles cellStyles = stylesSource.getCTStylesheet().getCellStyles();
if (cellStyles == null) {
cellStyles = CTCellStyles.Factory.newInstance();
}
List cellStyleArray = new ArrayList<>(cellStyles.getCellStyleList());
LOG.info("Exists : xfs={}, styleXfs={}, styles={}", xfs.size(), styleXfs.size(), cellStyleArray.size());
List newStyleXfs = new ArrayList<>();
List newCellStyles = new ArrayList<>();
// TODO: Consider removing styles in that is not referenced from any cell's "s" attribute ()
TreeSet usedStyleXfs = new TreeSet<>();
for (CTXf xf : xfs) {
usedStyleXfs.add((int) xf.getXfId());
}
// Change XfId references to the new ones
long newXfId = 0;
for (Integer usedStyleXf : usedStyleXfs) {
CTXf styleXf = styleXfs.get(usedStyleXf);
styleXf.setXfId(newXfId);
newStyleXfs.add(styleXf);
// Change xfId in if exists such named style
for (Iterator iterator = cellStyleArray.iterator(); iterator.hasNext(); ) {
CTCellStyle style = iterator.next();
if (style.getXfId() == usedStyleXf) {
style.setXfId(newXfId);
newCellStyles.add(style);
iterator.remove();
}
}
for (CTXf xf : xfs) {
if (xf.getXfId() == usedStyleXf) {
xf.setXfId(newXfId);
}
}
newXfId++;
}
LOG.info("Used : styleXfs={}, styles={}", newStyleXfs.size(), newCellStyles.size());
// Remove unused styles.
styleXfs.clear();
styleXfs.addAll(newStyleXfs);
cellStyles.setCount(newCellStyles.size());
cellStyles.setCellStyleArray(newCellStyles.toArray(new CTCellStyle[0]));
LOG.info("Style optimization has been finished.");
} catch (IllegalAccessException e) {
// Something is changed in POI implementation. Don't modify workbook, just quit.
LOG.error(e.getMessage(), e);
}
}
private XSSFOptimizer() {
}
}