Exemplo n.º 1
0
        private void CheckColumnWidth(int expectedWidth, int column, bool useMergedCells)
        {
            int bestFitWidth = tracker.GetBestFitColumnWidth(column, useMergedCells);

            if (bestFitWidth < 0 && expectedWidth < 0)
            {
                return;
            }
            double abs_error = Math.Abs(bestFitWidth - expectedWidth);
            double rel_error = abs_error / expectedWidth;

            if (rel_error > 0.25)
            {
                Assert.Fail("check column width: " +
                            rel_error + ", " + abs_error + ", " +
                            expectedWidth + ", " + bestFitWidth);
            }
        }
Exemplo n.º 2
0
        /**
         * Adjusts the column width to fit the contents.
         * <p>
         * This process can be relatively slow on large sheets, so this should
         *  normally only be called once per column, at the end of your
         *  processing.
         * </p>
         * You can specify whether the content of merged cells should be considered or ignored.
         *  Default is to ignore merged cells.
         *
         *  <p>
         *  Special note about SXSSF implementation: You must register the columns you wish to track with
         *  the SXSSFSheet using {@link #trackColumnForAutoSizing(int)} or {@link #trackAllColumnsForAutoSizing()}.
         *  This is needed because the rows needed to compute the column width may have fallen outside the
         *  random access window and been flushed to disk.
         *  Tracking columns is required even if all rows are in the random access window.
         *  </p>
         *  <p><i>New in POI 3.14 beta 1: auto-sizes columns using cells from current and flushed rows.</i></p>
         *
         * @param column the column index to auto-size
         * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
         */
        public void AutoSizeColumn(int column, bool useMergedCells)
        {
            // Multiple calls to autoSizeColumn need to look up the best-fit width
            // of rows already flushed to disk plus re-calculate the best-fit width
            // of rows in the current window. It isn't safe to update the column
            // widths before flushing to disk because columns in the random access
            // window rows may change in best-fit width. The best-fit width of a cell
            // is only fixed when it becomes inaccessible for modification.
            // Changes to the shared strings table, styles table, or formulas might
            // be able to invalidate the auto-size width without the opportunity
            // to recalculate the best-fit width for the flushed rows. This is an
            // inherent limitation of SXSSF. If having correct auto-sizing is
            // critical, the flushed rows would need to be re-read by the read-only
            // XSSF eventmodel (SAX) or the memory-heavy XSSF usermodel (DOM).
            int flushedWidth;

            try
            {
                // get the best fit width of rows already flushed to disk
                flushedWidth = _autoSizeColumnTracker.GetBestFitColumnWidth(column, useMergedCells);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Could not auto-size column. Make sure the column was tracked prior to auto-sizing the column.", e);
            }

            // get the best-fit width of rows currently in the random access window
            int activeWidth = (int)(256 * SheetUtil.GetColumnWidth(this, column, useMergedCells));

            // the best-fit width for both flushed rows and random access window rows
            // flushedWidth or activeWidth may be negative if column contains only blank cells
            int bestFitWidth = Math.Max(flushedWidth, activeWidth);

            if (bestFitWidth > 0)
            {
                int maxColumnWidth = 255 * 256; // The maximum column width for an individual cell is 255 characters
                int width          = Math.Min(bestFitWidth, maxColumnWidth);
                SetColumnWidth(column, width);
            }
        }