]> source.dussan.org Git - poi.git/commitdiff
support for auto-sizing worksheet columns
authorYegor Kozlov <yegor@apache.org>
Tue, 13 Feb 2007 16:25:55 +0000 (16:25 +0000)
committerYegor Kozlov <yegor@apache.org>
Tue, 13 Feb 2007 16:25:55 +0000 (16:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@507076 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/hssf/quick-guide.xml
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java

index 6c3d964d0c30a1eb90ba72dd3b2663b3455228bb..470dcb45899afaa52b3fb3a7b0cb9c9fb414bbc0 100644 (file)
@@ -65,6 +65,7 @@
                     <li><link href="#Images">Images</link></li>
                     <li><link href="#NamedRanges">Named Ranges and Named Cells</link></li>
                     <li><link href="#CellComments">How to set cell comments</link></li>
+                    <li><link href="#Autofit">How to adjust column width to fit the contents</link></li>
                 </ul>
             </section>
             <section><title>Features</title>
     HSSFWorkbook wb = new HSSFWorkbook();
     HSSFSheet sheet = wb.createSheet("format sheet");
     HSSFPrintSetup ps = sheet.getPrintSetup();
-    
+
     sheet.setAutobreaks(true);
-    
+
     ps.setFitHeight((short)1);
     ps.setFitWidth((short)1);
 
     wb.setPrintArea(0, "$A$1:$C$2");
     //sets the print area for the first sheet
     //Alternatively:
-    //wb.setPrintArea(0, 0, 1, 0, 0) is equivalent to using the name reference (See the JavaDocs for more details)  
+    //wb.setPrintArea(0, 0, 1, 0, 0) is equivalent to using the name reference (See the JavaDocs for more details)
 
     // Create various cells and rows for spreadsheet.
 
     FileOutputStream fileOut = new FileOutputStream("workbook.xls");
     wb.write(fileOut);
     fileOut.close();
-    
-    
+
+
                     </source>
                 </section>
 
     HSSFWorkbook wb = new HSSFWorkbook();
     HSSFSheet sheet = wb.createSheet("format sheet");
     HSSFFooter footer = sheet.getFooter()
-    
+
     footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );
-    
+
 
 
     // Create various cells and rows for spreadsheet.
     wb.write(fileOut);
     fileOut.close();
                     </source>
-                </section>                
-                
+                </section>
+
                 <anchor id="ConvenienceFunctions"/>
                 <section><title>Using the Convenience Functions</title>
                     <p>
     wb.write(fileOut);
     fileOut.close();
                     </source>
-                </section>                
+                </section>
 
                 <anchor id="SelectSheet"/>
                 <section><title>Set a sheet as selected</title>
     wb.write(fileOut);
     fileOut.close();
                     </source>
-                </section>                
+                </section>
 
                 <anchor id="Zoom"/>
                 <section><title>Set the zoom magnification</title>
     HSSFHeader header = sheet.getHeader();
     header.setCenter("Center Header");
     header.setLeft("Left Header");
-    header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + 
+    header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +
                     HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");
 
     FileOutputStream fileOut = new FileOutputStream("workbook.xls");
         <section>
             <title>Named Ranges and Named Cells</title>
             <p>
-                Named Range is a way to refer to a group of cells by a name. Named Cell is a 
+                Named Range is a way to refer to a group of cells by a name. Named Cell is a
                 degenerate case of Named Range in that the 'group of cells' contains exactly one
                 cell. You can create as well as refer to cells in a workbook by their named range.
-                When working with Named Ranges, the classes: org.apache.poi.hssf.util.CellReference and 
+                When working with Named Ranges, the classes: org.apache.poi.hssf.util.CellReference and
                 &amp; org.apache.poi.hssf.util.AreaReference are used.
             </p>
             <p>
     HSSFWorkbook wb = new HSSFWorkbook();
     HSSFSheet sheet = wb.createSheet(sname);
     sheet.createRow(0).createCell((short) 0).setCellValue(cvalue);
-     
+
     // 1. create named range for a single cell using areareference
     HSSFName namedCell = wb.createName();
     namedCell.setNameName(cname);
     String reference = sname+"!A1:A1"; // area reference
     namedCell.setReference(reference);
-    
+
     // 2. create named range for a single cell using cellreference
     HSSFName namedCell = wb.createName();
     namedCell.setNameName(cname);
     String reference = sname+"!A1"; // cell reference
     namedCell.setReference(reference);
-    
+
     // 3. create named range for an area using AreaReference
     HSSFName namedCell = wb.createName();
     namedCell.setNameName(cname);
     String reference = sname+"!A1:C5"; // area reference
     namedCell.setReference(reference);
-    
+
             </source>
             <p>
             Reading from Named Range / Named Cell
     // retrieve the named range
     int namedCellIdx = wb.getNameIndex(cellName);
     HSSFName aNamedCell = wb.getNameAt(namedCellIdx);
-    
+
     // retrieve the cell at the named range and test its contents
     AreaReference aref = new AreaReference(aNamedCell.getReference());
     CellReference[] crefs = aref.getCells();
         // extract the cell contents based on cell type etc.
     }
             </source>
-            
+
         </section>
         <anchor id="CellComments"/>
         <section><title>Cell Comments</title>
 
     comment2.setString(string);
     //by default comments are hidden. This one is always visible.
-    comment2.setVisible(true); 
+    comment2.setVisible(true);
 
     comment2.setAuthor("Bill Gates");
 
         </p>
         <source>
     HSSFCell cell = sheet.get(3).getColumn((short)1);
-    HSSFComment comment = cell.getCellComment(); 
+    HSSFComment comment = cell.getCellComment();
     if (comment != null) {
       HSSFRichTextString str = comment.getString();
       String author = comment.getAuthor();
     }
        </source>
      </section>
+     <anchor id="Autofit"/>
+     <section><title>Adjust column width to fit the contents</title>
+        <source>
+    HSSFSheet sheet = workbook.getSheetAt(0);
+    sheet.autoSizeColumn((short)0); //adjust width of the first column
+    sheet.autoSizeColumn((short)1); //adjust width of the second column
+        </source>
+
+     </section>
 
     </body>
 </document>
index 574535c70ebbceea9b101b5dea7517631bd67bd9..9c3c147a68710d85d5ff336fdf639f7bc11afd98 100644 (file)
@@ -36,6 +36,12 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.TreeMap;
+import java.text.AttributedString;
+import java.text.NumberFormat;
+import java.text.DecimalFormat;
+import java.awt.font.TextLayout;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextAttribute;
 
 /**
  * High level representation of a worksheet.
@@ -44,6 +50,7 @@ import java.util.TreeMap;
  * @author  Libin Roman (romal at vistaportal.com)
  * @author  Shawn Laubach (slaubach at apache dot org) (Just a little)
  * @author  Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little, too)
+ * @author  Yegor Kozlov (yegor at apache.org) (Autosizing columns)
  */
 
 public class HSSFSheet
@@ -1381,4 +1388,96 @@ public class HSSFSheet
     public void setDefaultColumnStyle(short column, HSSFCellStyle style) {
        sheet.setColumn(column, new Short(style.getIndex()), null, null, null, null);
     }
+
+    /**
+     * Adjusts the column width to fit the contents.
+     *
+     * @param column the column index
+     */
+    public void autoSizeColumn(short column) {
+        AttributedString str;
+        TextLayout layout;
+        /**
+         * Excel measures columns in units of 1/256th of a character width
+         * but the docs say nothing about what particular character is used.
+         * '0' looks a good choice.
+         */
+        char defaultChar = '0';
+       
+        FontRenderContext frc = new FontRenderContext(null, true, true);
+
+        HSSFWorkbook wb = new HSSFWorkbook(book);
+        HSSFFont defaultFont = wb.getFontAt((short) 0);
+
+        str = new AttributedString("" + defaultChar);
+        str.addAttribute(TextAttribute.FAMILY, defaultFont.getFontName());
+        str.addAttribute(TextAttribute.SIZE, new Float(defaultFont.getFontHeightInPoints()));
+        layout = new TextLayout(str.getIterator(), frc);
+        int defaultCharWidth = (int)layout.getAdvance();
+
+        double width = -1;
+        for (Iterator it = rowIterator(); it.hasNext();) {
+            HSSFRow row = (HSSFRow) it.next();
+            HSSFCell cell = row.getCell(column);
+            if (cell == null) continue;
+
+            HSSFCellStyle style = cell.getCellStyle();
+            HSSFFont font = wb.getFontAt(style.getFontIndex());
+            if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
+                HSSFRichTextString rt = cell.getRichStringCellValue();
+                String[] lines = rt.getString().split("\\n");
+                for (int i = 0; i < lines.length; i++) {
+                    str = new AttributedString(lines[i] + defaultChar);
+                    str.addAttribute(TextAttribute.FAMILY, font.getFontName());
+                    str.addAttribute(TextAttribute.SIZE, new Float(font.getFontHeightInPoints()));
+                    if (font.getBoldweight() == HSSFFont.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+                    if (rt.numFormattingRuns() > 0) {
+                        for (int j = 0; j < lines[i].length(); j++) {
+                            int idx = rt.getFontAtIndex(j);
+                            if (idx != 0) {
+                                HSSFFont fnt = wb.getFontAt((short) idx);
+                                str.addAttribute(TextAttribute.FAMILY, fnt.getFontName(), j, j + 1);
+                                str.addAttribute(TextAttribute.SIZE, new Float(fnt.getFontHeightInPoints()), j, j + 1);
+                            }
+                        }
+                    }
+                    layout = new TextLayout(str.getIterator(), frc);
+                    width = Math.max(width, layout.getAdvance() / defaultCharWidth);
+                }
+            } else {
+                String sval = null;
+                if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
+                    HSSFDataFormat dataformat = wb.createDataFormat();
+                    short idx = style.getDataFormat();
+                    String format = dataformat.getFormat(idx).replaceAll("\"", "");
+                    double value = cell.getNumericCellValue();
+                    try {
+                        NumberFormat fmt;
+                        if ("General".equals(format))
+                            fmt = new DecimalFormat();
+                        else
+                            fmt = new DecimalFormat(format);
+                        sval = fmt.format(value);
+                    } catch (Exception e) {
+                        sval = "" + value;
+                    }
+                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+                    sval = cell.getCellFormula();
+                } else if (cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
+                    sval = String.valueOf(cell.getBooleanCellValue());
+                }
+
+                str = new AttributedString(sval + defaultChar);
+                str.addAttribute(TextAttribute.FAMILY, font.getFontName());
+                str.addAttribute(TextAttribute.SIZE, new Float(font.getFontHeightInPoints()));
+                layout = new TextLayout(str.getIterator(), frc);
+                width = Math.max(width, layout.getAdvance() / defaultCharWidth);
+            }
+
+            if (width != -1) {
+                sheet.setColumnWidth(column, (short) (width * 256));
+            }
+        }
+    }
+
 }