4

I'm using JXLS 2.3.0 with apache poi implementation.
And I use following code to create excel :

try{
   InputStream is = ObjectCollectionDemo.class.getResourceAsStream("/template.xls")
   OutputStream os = new FileOutputStream("target/output.xls")  
   Context context = new Context();
   context.putVar("employees", employees);
   JxlsHelper.getInstance().processTemplate(is, os, context);

   }

my generated excel file looks like next :

enter image description here

As above screenshot shows, the first 'Name' value only display partial.

But what I want is :

enter image description here

That is the content in excel cell can be wrapped and the row height can auto fit the cell content.

How can I do that? Thanks in advance.

-------------- Updated -----------------

the solution is:

  1. did as @Andy said
  2. format the corresponding cell as wrap text in your template file
  3. (optional) after step 1 and 2, the 99% info of cell content can be shown, but still miss some. Then I open the template file and found it looks like next:

enter image description here

we can found that the } of ${a.name} is on the new line, change it to:

enter image description here

that is make ${a.name} is on one line, then all content can be shown.

frank
  • 1,169
  • 18
  • 43

2 Answers2

5

I know this post is quite old, but i stumbled upon it as one of the first Google hits, and want to share my solution.

I implemented the auto-row-height feature for MS Excel 2010 in 3 steps.

Create a Command:

public class AutoRowHeightCommand extends AbstractCommand {

    // ... left out boilerplate

    @Override
    public Size applyAt(CellRef cellRef, Context context) {
        Size size = this.area.applyAt(cellRef, context);

        PoiTransformer transformer = (PoiTransformer) area.getTransformer();
        Row row = transformer.getWorkbook().getSheet(cellRef.getSheetName()).getRow(cellRef.getRow());
        row.setHeight((short) -1);

        return size;
    }
}

Configure the command to be used

// static method call:
XlsCommentAreaBuilder.addCommandMapping("autoRowHeight", AutoRowHeightCommand.class);

JxlsHelper.getInstance().processTemplate(is, os, context);

Make use of the command

In the template.xlsx file edit the cell-comment that already contains the loop-command, and add the autoRowHeight command as a new line, e.g.:

jx:each(items="myitems", var="i", lastCell="B4")
jx:autoRowHeight(lastCell="B4")

Thanks to Leonid Vysochyn and Franz Frühwirth, who lead me to this solution.

Andy
  • 1,964
  • 1
  • 15
  • 29
  • it's appreciated that you post your answer. I did as you said, but I failed, the cell content still cannot be wrap. What I missed? @Andy – frank Mar 05 '18 at 14:28
  • @frank hard to tell without any further information. First: are you using MS Excel? Which version? I've tested with MS Excel 2010, but the Solution by F. Frühwirth is inteded to work for 2013. Next: is the command executed at all? Put a breakpoint in `AutoRowHeightCommand` or add some log-output to see what happens. – Andy Mar 05 '18 at 15:50
  • Please see my updated part at my bottom of question. First, this command works, because when I change `row.setHeight((short)-1)` to `row.setHeigh(3000)`, then the row height is increase much. Second, I am using MS Excel 2016. – frank Mar 14 '18 at 13:35
  • @frank hm... have you tried to put spaces within the values? As far as I understand it, the cell height is calculated by Excel, and I can imagine it has problems calculating it for one long value. – Andy Mar 14 '18 at 13:47
  • 1
    Hello @Andy, your soution works for me on Jxls ver. 2.4.5. The affected cells in template need to be setted like this: 1) Select cells to be formattted, than Cells -> Format -> Fit height of rows, 2) Alignment -> Wrapping text. Notice: Very important is to use original Excel. For example, Libre Office Calc doesn't display cells corectly. – hariprasad Jul 03 '18 at 18:50
  • @chiahao glad to hear. Please click 'upvote' then. Thanks. – Andy Nov 09 '18 at 07:01
  • Hi @Andy, now I found that custom `autoRowHeight` command not work for merged cell, do you find the solution yet? – frank Apr 12 '19 at 02:42
  • @frank sorry, can't help. – Andy Apr 13 '19 at 05:53
  • not work for streaming workbook, or just need additional if for SXSSFRow in removeDyDescentAttr method – devalurum Jul 17 '23 at 01:56
1

I have the same issue with Excel 2016. I created a xlsx-template and used the same solution row.setHeight((short) -1) , but it doesn't work because Excel 2016 adds dyDescent attribute to the row definition in the template. I couldn't find a way how to force Excel not to set this attribute.

The dyDescent attribute has a side effect; it sets the customHeight attribute to true even if the customHeight attribute is explicitly set to false.

I'am not sure, that you can implement this for xls-template, but... Here is my workaround:

    @Override
    public Size applyAt(CellRef cellRef, Context context) {
       // code from @Andy example 
        Row row = .....
        removeDyDescentAttr(row);
        return size;
    }

    private void removeDyDescentAttr(Row row) {
        XSSFRow xssfRow = (XSSFRow) row;
        CTRowImpl ctRow = (CTRowImpl) xssfRow.getCTRow();
        QName dyDescent = new QName("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
        if (ctRow.get_store().find_attribute_user(dyDescent) != null) {
           ctRow.get_store().remove_attribute(dyDescent);
        }
    }
Sergey
  • 11
  • 3
  • @frank, I've updated my answer. Please look at it. And if you still need a complete code, just let me know and I prepare a project and push it to the github. – Sergey Dec 18 '18 at 19:02
  • I tried but there is ClassCastException for `XSSFRow`. If it is ok then please share your complete project in github, thanks! – frank Dec 19 '18 at 06:34
  • I suppose, that in your case Row has HSSFRow type, because you use **xls-template**. But my workaround is applicable only for **xlsx-templates**. Can you save your template in xlsx? – Sergey Dec 19 '18 at 08:13
  • I changed to **xlsx-template**, now it throws `indexoutofboundsexception` for `ctRow.get_store().remove_attribute(new QName("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac", "dyDescent"))` – frank Dec 19 '18 at 08:34
  • @frank please look at https://github.com/UdalovSergey/jxls-auto-fit-row-example. Here is a full example. Your last exception rise because your template doesn't contain dyDescent attribute. – Sergey Dec 19 '18 at 09:53
  • It works base on your new and complete `removeDyDescentAttr()` – frank Dec 20 '18 at 01:32
  • I tried your code with your `xlsx` template, it works! However, it failed if I create my `xlsx` template file(also with your code). `test.xslx` of https://github.com/takeAction/jxls-auto-fit-row-example is my template file, and I can't tell where there is difference between my template file with yours. It's appreciated if you could check, Thanks! – frank Apr 28 '22 at 01:48