Search code examples
javaexcelapache-poijxls

JXLS ignores template style, how can I force it to keep the column widths as they are in the template file?


I am using JXLS to generate an excel file using a custom template. The template is simply the standard grid export template that comes with the library, except I have changed the width of some of the columns in the template file. My code is mostly just a copy of the sample code.

 private void exportAsXLS(List<CalExportItem> exportItems, OutputStream os1) {

    try (InputStream is = CalDataExporter.class.getClassLoader().getResourceAsStream(TEMPLATE_FILEPATH)) {
        xlsExporter.registerGridTemplate(is);
        xlsExporter.gridExport(Arrays.asList(HEADERS), exportItems, FIELDS, os1);
    } catch (Exception e) {
        LOGGER.error("Exception exporting as XLS", e);
    }
}

I have basically just copied the "SimpleExporter" sample

public class CalXlsExportHelper {

private static final Logger LOGGER = LoggerFactory.getLogger(CalXlsExportHelper.class);

private byte[] templateBytes;

public void registerGridTemplate(InputStream inputStream) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    byte[] data = new byte[4096];
    int count;
    while ((count = inputStream.read(data)) != -1) {
        os.write(data, 0, count);
    }
    templateBytes = os.toByteArray();
}

public void gridExport(Iterable headers, Iterable dataObjects, String objectProps, OutputStream outputStream) {
    InputStream is = new ByteArrayInputStream(templateBytes);
    Transformer transformer = TransformerFactory.createTransformer(is, outputStream);

    //******** key difference with SimpleExporter ********
    // Passing false to areaBuilder in order to prevent clearing of cells and loss of template style
    AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer, false);

    List<Area> xlsAreaList = areaBuilder.build();
    Area xlsArea = xlsAreaList.get(0);
    Context context = new Context();
    context.putVar("headers", headers);
    context.putVar("data", dataObjects);
    GridCommand gridCommand = (GridCommand) xlsArea.getCommandDataList().get(0).getCommand();
    gridCommand.setProps(objectProps);
    xlsArea.applyAt(new CellRef("Sheet1!A1"), context);
    try {
        transformer.write();
    } catch (IOException e) {
        LOGGER.error("Failed to write to output stream", e);
        throw new JxlsException("Failed to write to output stream", e);
    }
}

}

And this is what I have in the template file:

Author:
jx:area(lastCell="A3")

jx:grid(lastCell="A3" headers="headers" data="data" areas=[A2:A2, A3:A3]  
   formatCells="String:A3,Integer:B3,Long:B3,Short:B3,Double:B3,Float:B3,BigDecimal:B3")

Solution

  • With SimpleExporter there is no option to configure this because you cannot modify Context and Transformer objects used during export.

    But if you use other ways to export you will have the following options

    1. Use Transformer setIgnoreColumnProps and setIgnoreRowProps methods to ignore column/row widths for example

      ((PoiTransformer)transformer).setIgnoreColumnProps(true);
      ((PoiTransformer)transformer).setIgnoreRowProps(true);
      
    2. Use Context.Config to set ignoring of all source cell styles context.getConfig().setIgnoreSourceCellStyle(true)