View | Details | Raw Unified | Return to bug 57450
Collapse All | Expand All

(-)src/java/org/apache/poi/ss/util/SheetUtil.java (-2 / +2 lines)
Lines 227-233 Link Here
227
     * @param wb the workbook to get the default character width from
227
     * @param wb the workbook to get the default character width from
228
     * @return default character width
228
     * @return default character width
229
     */
229
     */
230
    private static int getDefaultCharWidth(final Workbook wb) {
230
    public static int getDefaultCharWidth(final Workbook wb) {
231
        Font defaultFont = wb.getFontAt((short) 0);
231
        Font defaultFont = wb.getFontAt((short) 0);
232
232
233
        AttributedString str = new AttributedString(String.valueOf(defaultChar));
233
        AttributedString str = new AttributedString(String.valueOf(defaultChar));
Lines 248-254 Link Here
248
     * @param useMergedCells    whether to use merged cells
248
     * @param useMergedCells    whether to use merged cells
249
     * @return  the width in pixels or -1 if cell is empty
249
     * @return  the width in pixels or -1 if cell is empty
250
     */
250
     */
251
    private static double getColumnWidthForRow(
251
    public static double getColumnWidthForRow(
252
            Row row, int column, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) {
252
            Row row, int column, int defaultCharWidth, DataFormatter formatter, boolean useMergedCells) {
253
        if( row == null ) {
253
        if( row == null ) {
254
            return -1;
254
            return -1;
(-)src/ooxml/java/org/apache/poi/xssf/streaming/AutosizeColumnTracker.java (+83 lines)
Line 0 Link Here
1
/* ====================================================================
2
   Licensed to the Apache Software Foundation (ASF) under one or more
3
   contributor license agreements.  See the NOTICE file distributed with
4
   this work for additional information regarding copyright ownership.
5
   The ASF licenses this file to You under the Apache License, Version 2.0
6
   (the "License"); you may not use this file except in compliance with
7
   the License.  You may obtain a copy of the License at
8
9
       http://www.apache.org/licenses/LICENSE-2.0
10
11
   Unless required by applicable law or agreed to in writing, software
12
   distributed under the License is distributed on an "AS IS" BASIS,
13
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
   See the License for the specific language governing permissions and
15
   limitations under the License.
16
==================================================================== */
17
18
package org.apache.poi.xssf.streaming;
19
20
import java.util.HashMap;
21
import java.util.HashSet;
22
import java.util.Map;
23
import java.util.Set;
24
25
import org.apache.poi.ss.usermodel.DataFormatter;
26
import org.apache.poi.ss.usermodel.Row;
27
import org.apache.poi.ss.util.SheetUtil;
28
29
/**
30
 * Tracks maximum column width when adding rows to an SXSSF sheet
31
 * so the column width can be calculated although not all rows are
32
 * held in memory.
33
*/
34
public class AutosizeColumnTracker {
35
    private SXSSFSheet sheet;
36
    private int defaultCharWidth = -1;
37
38
    private final Set<Integer> monitoredColumns = new HashSet<Integer>();
39
    private final Map<Integer, Double> maxColumnWidths = new HashMap<Integer, Double>();
40
    private DataFormatter dataFormatter;
41
42
    public AutosizeColumnTracker(SXSSFSheet sheet) {
43
        this.sheet = sheet;
44
    }
45
46
    public void monitorColumn(int columnIndex) {
47
        monitoredColumns.add(columnIndex);
48
    }
49
50
    public void trackRow(Row row) {
51
        trackRow(row, false);
52
    }
53
54
    public void trackRow(Row row, boolean useMergedCells) {
55
56
        if (defaultCharWidth < 0) {
57
            defaultCharWidth = SheetUtil.getDefaultCharWidth(sheet.getWorkbook());
58
        }
59
60
        if (dataFormatter == null) {
61
            dataFormatter = new DataFormatter();
62
        }
63
64
        for (int monitoredColumn : monitoredColumns) {
65
            final double columnWidth = SheetUtil.getColumnWidthForRow(row, monitoredColumn, defaultCharWidth,
66
                                                                      dataFormatter, useMergedCells);
67
            if (!maxColumnWidths.containsKey(monitoredColumn) || columnWidth > maxColumnWidths.get(monitoredColumn)) {
68
                maxColumnWidths.put(monitoredColumn, columnWidth);
69
            }
70
        }
71
    }
72
73
    public void applyAutosizeToColumn(int columnIndex) {
74
        if (maxColumnWidths.containsKey(columnIndex)) {
75
76
            double maxColumnWidth = maxColumnWidths.get(columnIndex);
77
            maxColumnWidth = Math.min(maxColumnWidth, 255); // The maximum column width for an individual cell is 255 characters
78
            sheet.setColumnWidth(columnIndex, (int) (maxColumnWidth*256));
79
        }
80
    }
81
82
}
83
native
(-)src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java (+41 lines)
Lines 19-30 Link Here
19
19
20
import static org.junit.Assert.assertEquals;
20
import static org.junit.Assert.assertEquals;
21
21
22
import java.io.IOException;
23
22
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
24
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
25
import org.apache.poi.ss.usermodel.Cell;
26
import org.apache.poi.ss.usermodel.Font;
23
import org.apache.poi.ss.usermodel.PrintSetup;
27
import org.apache.poi.ss.usermodel.PrintSetup;
28
import org.apache.poi.ss.usermodel.Row;
24
import org.apache.poi.ss.usermodel.Sheet;
29
import org.apache.poi.ss.usermodel.Sheet;
25
import org.apache.poi.ss.usermodel.Workbook;
30
import org.apache.poi.ss.usermodel.Workbook;
31
import org.apache.poi.ss.util.SheetUtil;
26
import org.apache.poi.xssf.SXSSFITestDataProvider;
32
import org.apache.poi.xssf.SXSSFITestDataProvider;
27
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
33
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
34
import org.junit.Assume;
28
import org.junit.Ignore;
35
import org.junit.Ignore;
29
import org.junit.Test;
36
import org.junit.Test;
30
37
Lines 77-80 Link Here
77
        wb1.close();
84
        wb1.close();
78
        wb2.close();
85
        wb2.close();
79
    }
86
    }
87
88
    @Ignore("Shows the problem that Bug 57450 will fix")
89
    @Test
90
    public final void bug57450_testAutoSizeWithStreamingAndSmallWindow() throws IOException {
91
        SXSSFWorkbook wb = new SXSSFWorkbook(null, 1); // Window size 1 so only last row will be in memory
92
        Sheet sheet = wb.createSheet("Sheet1");
93
94
        Row row0 = sheet.createRow(0);
95
        Cell cellRow0 = row0.createCell(0);
96
        String longValue = "www.hostname.com, www.hostname.com, " +
97
                           "www.hostname.com, www.hostname.com, www.hostname.com, " +
98
                           "www.hostname.com, www.hostname.com, www.hostname.com, " +
99
                           "www.hostname.com, www.hostname.com, www.hostname.com, " +
100
                           "www.hostname.com, www.hostname.com, www.hostname.com, " +
101
                           "www.hostname.com, www.hostname.com, www.hostname.com, www.hostname.com";
102
        cellRow0.setCellValue(longValue);
103
104
        Row row1 = sheet.createRow(1);
105
        Cell cellRow1 = row1.createCell(0);
106
        String shortValue = "www.hostname.com";
107
        cellRow1.setCellValue(shortValue);
108
109
        // autoSize will fail if required fonts are not installed, skip this test then
110
        Font font = wb.getFontAt(cellRow0.getCellStyle().getFontIndex());
111
        Assume.assumeTrue("Cannot verify autoSizeColumn() because the necessary Fonts are not installed on this machine: " + font,
112
                          SheetUtil.canComputeColumnWidth(font));
113
114
        sheet.autoSizeColumn(0);
115
116
        assertEquals("Expected maximum column width 255*256, but found ", 255 * 256, sheet.getColumnWidth(0));
117
118
        wb.close();
119
    }
120
80
}
121
}

Return to bug 57450