Browse Source

Merge pull request #97 from energyworldnet/autosizecolumn-fix

Fix AutoSizeColumn
master^2
Savorboard 6 years ago
committed by GitHub
parent
commit
947220dedb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/NPOI/SS/UserModel/DataFormatter.cs
  2. 30
      src/NPOI/SS/Util/Format.cs
  3. 60
      src/NPOI/SS/Util/SheetUtil.cs
  4. 26
      src/NPOI/TextRenderer.cs

4
src/NPOI/SS/UserModel/DataFormatter.cs

@ -118,10 +118,10 @@ namespace NPOI.SS.UserModel
invalidDateTimeString = buf.ToString();
}
/** <em>General</em> FormatBase for whole numbers. */
private static DecimalFormat generalWholeNumFormat = new DecimalFormat("0");
private static DecimalFormat generalWholeNumFormat = new DecimalFormat("0", true);
/** <em>General</em> FormatBase for decimal numbers. */
private static DecimalFormat generalDecimalNumFormat = new DecimalFormat("#.##########");
private static DecimalFormat generalDecimalNumFormat = new DecimalFormat("#.##########", true);
/** A default FormatBase to use when a number pattern cannot be Parsed. */
private FormatBase defaultNumFormat;

30
src/NPOI/SS/Util/Format.cs

@ -173,12 +173,20 @@ namespace NPOI.SS.Util
private string pattern;
private bool isGeneral;
public DecimalFormat(string pattern)
{
if (pattern.IndexOf("'", StringComparison.Ordinal) != -1)
throw new ArgumentException("invalid pattern");
this.pattern = pattern;
}
internal DecimalFormat(string pattern, bool isGeneral) : this(pattern)
{
this.isGeneral = isGeneral;
}
public string Pattern
{
get
@ -194,19 +202,19 @@ namespace NPOI.SS.Util
}
public override string Format(object obj, CultureInfo culture)
{
//invalide fraction
// Invalid fraction
pattern = RegexFraction.Replace(pattern, "/");
double n = Convert.ToDouble(obj, CultureInfo.InvariantCulture);
if (pattern.IndexOf("'", StringComparison.Ordinal) != -1)
{
//return ((double)obj).ToString();
return Convert.ToDouble(obj, CultureInfo.InvariantCulture).ToString(culture);
}
else
{
return Convert.ToDouble(obj, CultureInfo.InvariantCulture).ToString(pattern, culture);
//return ((double)obj).ToString(pattern) ;
}
return n.ToString(culture);
// Excel displays in scientific notation if the cell form is General and there are 12 or more digits
// https://support.office.com/en-us/article/display-numbers-in-scientific-exponential-notation-f85a96c0-18a1-4249-81c3-e934cd2aae25
if (isGeneral && Math.Floor(Math.Log10(n) + 1) >= 12)
pattern = "E4";
return n.ToString(pattern, culture);
}
public override StringBuilder Format(object obj, StringBuilder toAppendTo, CultureInfo culture)

60
src/NPOI/SS/Util/SheetUtil.cs

@ -36,7 +36,7 @@ namespace NPOI.SS.Util
// * but the docs say nothing about what particular character is used.
// * '0' looks to be a good choice.
// */
private static char defaultChar = '0';
private const char defaultChar = '0';
// /**
// * This is the multiple that the font height is scaled by when determining the
@ -300,19 +300,18 @@ namespace NPOI.SS.Util
ICellStyle style = cell.CellStyle;
CellType cellType = cell.CellType;
IFont defaultFont = wb.GetFontAt((short)0);
Font windowsFont = IFont2Font(defaultFont);
// for formula cells we compute the cell width for the cached formula result
if (cellType == CellType.Formula) cellType = cell.CachedFormulaResultType;
IFont font = wb.GetFontAt(style.FontIndex);
Font windowsFont = IFont2Font(font);
//AttributedString str;
//TextLayout layout;
double width = -1;
using (Bitmap bmp = new Bitmap(1, 1))
using (Graphics g = Graphics.FromImage(bmp))
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
if (cellType == CellType.String)
{
@ -324,7 +323,6 @@ namespace NPOI.SS.Util
//str = new AttributedString(txt);
//copyAttributes(font, str, 0, txt.length());
windowsFont = IFont2Font(font);
if (rt.NumFormattingRuns > 0)
{
// TODO: support rich text fragments
@ -345,11 +343,11 @@ namespace NPOI.SS.Util
// AffineTransform.getScaleInstance(1, fontHeightMultiple)
// );
double angle = style.Rotation * 2.0 * Math.PI / 360.0;
SizeF sf = g.MeasureString(txt, windowsFont);
SizeF sf = MeasureString(g, txt, windowsFont);
double x1 = Math.Abs(sf.Height * Math.Sin(angle));
double x2 = Math.Abs(sf.Width * Math.Cos(angle));
double w = Math.Round(x1 + x2, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w / colspan / defaultCharWidth) * 2 + cell.CellStyle.Indention);
width = Math.Max(width, (w / colspan / defaultCharWidth) + cell.CellStyle.Indention);
//width = Math.Max(width,
// ((layout.getOutline(trans).getBounds().getWidth()/colspan)/defaultCharWidth) +
// cell.getCellStyle().getIndention());
@ -359,8 +357,8 @@ namespace NPOI.SS.Util
//width = Math.Max(width,
// ((layout.getBounds().getWidth()/colspan)/defaultCharWidth) +
// cell.getCellStyle().getIndention());
double w = Math.Round(g.MeasureString(txt, windowsFont).Width, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w / colspan / defaultCharWidth) * 2 + cell.CellStyle.Indention);
double w = Math.Round(MeasureString(g, txt, windowsFont).Width, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w / colspan / defaultCharWidth) + cell.CellStyle.Indention);
}
}
}
@ -388,7 +386,6 @@ namespace NPOI.SS.Util
String txt = sval + defaultChar;
//str = new AttributedString(txt);
//copyAttributes(font, str, 0, txt.length());
windowsFont = IFont2Font(font);
//layout = new TextLayout(str.getIterator(), fontRenderContext);
if (style.Rotation != 0)
{
@ -407,19 +404,19 @@ namespace NPOI.SS.Util
// ((layout.getOutline(trans).getBounds().getWidth()/colspan)/defaultCharWidth) +
// cell.getCellStyle().getIndention());
double angle = style.Rotation * 2.0 * Math.PI / 360.0;
SizeF sf = g.MeasureString(txt, windowsFont);
SizeF sf = MeasureString(g, txt, windowsFont);
double x1 = sf.Height * Math.Sin(angle);
double x2 = sf.Width * Math.Cos(angle);
double w = Math.Round(x1 + x2, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w / colspan / defaultCharWidth) * 2 + cell.CellStyle.Indention);
width = Math.Max(width, (w / colspan / defaultCharWidth) + cell.CellStyle.Indention);
}
else
{
//width = Math.max(width,
// ((layout.getBounds().getWidth()/colspan)/defaultCharWidth) +
// cell.getCellStyle().getIndention());
double w = Math.Round(g.MeasureString(txt, windowsFont).Width, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w * 1.0 / colspan / defaultCharWidth) * 2 + cell.CellStyle.Indention);
double w = Math.Round(MeasureString(g, txt, windowsFont).Width, 0, MidpointRounding.ToEven);
width = Math.Max(width, (w / colspan / defaultCharWidth) + cell.CellStyle.Indention);
}
}
}
@ -449,14 +446,12 @@ namespace NPOI.SS.Util
IWorkbook wb = sheet.Workbook;
DataFormatter formatter = new DataFormatter();
IFont defaultFont = wb.GetFontAt((short)0);
//str = new AttributedString((defaultChar));
//copyAttributes(defaultFont, str, 0, 1);
//layout = new TextLayout(str.Iterator, fontRenderContext);
//int defaultCharWidth = (int)layout.Advance;
Font font = IFont2Font(defaultFont);
int defaultCharWidth = TextRenderer.MeasureText("" + new String(defaultChar, 1), font).Width;
int defaultCharWidth = getDefaultCharWidth(wb);
//DummyEvaluator dummyEvaluator = new DummyEvaluator();
double width = -1;
@ -491,14 +486,11 @@ namespace NPOI.SS.Util
IWorkbook wb = sheet.Workbook;
DataFormatter formatter = new DataFormatter();
IFont defaultFont = wb.GetFontAt((short)0);
//str = new AttributedString((defaultChar));
//copyAttributes(defaultFont, str, 0, 1);
//layout = new TextLayout(str.Iterator, fontRenderContext);
//int defaultCharWidth = (int)layout.Advance;
Font font = IFont2Font(defaultFont);
int defaultCharWidth = TextRenderer.MeasureText("" + new String(defaultChar, 1), font).Width;
int defaultCharWidth = getDefaultCharWidth(wb);
double width = -1;
for (int rowIdx = firstRow; rowIdx <= lastRow; ++rowIdx)
@ -662,15 +654,23 @@ namespace NPOI.SS.Util
public static int getDefaultCharWidth(IWorkbook wb)
{
//TODO: Implement!
return 1;
//throw new NotImplementedException();
//IFont defaultFont = wb.GetFontAt(0);
IFont defaultFont = wb.GetFontAt(0);
Font font = IFont2Font(defaultFont);
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
double width = MeasureString(g, new string(defaultChar, 1), font).Width;
return (int)Math.Round(width, 0, MidpointRounding.ToEven);
}
}
private static SizeF MeasureString(Graphics g, string text, Font font)
{
var size = g.MeasureString(text, font);
//IAttributedString str = new AttributedString(defaultChar.ToString());
//copyAttributes(defaultFont, str, 0, 1);
//ITextLayout layout = new TextLayout(str.getIterator(), fontRenderContext);
//return (int)layout.getAdvance();
// MeasureString adds padding so we do this to remove it
// https://stackoverflow.com/a/11708952/1409101
var actualWidth = g.MeasureString(text + text, font).Width - size.Width;
return new SizeF(actualWidth, size.Height);
}
}
}

26
src/NPOI/TextRenderer.cs

@ -1,26 +0,0 @@
using System.Drawing;
namespace NPOI
{
/// <summary>Provides methods used to measure and render text. This class cannot be inherited. </summary>
public sealed class TextRenderer
{
private TextRenderer()
{
}
/// <summary>Provides the size, in pixels, of the specified text when drawn with the specified font.</summary>
/// <param name="text">The text to measure.</param>
/// <param name="font">The <see cref="T:Color" /> to apply to the measured text.</param>
/// <returns>The <see cref="T:System.Drawing.Size" />, in pixels, of <paramref name="text" /> drawn on a single line with the specified <paramref name="font" />. You can manipulate how the text is drawn by using one of the <see cref="M:System.Windows.Forms.TextRenderer.DrawText(System.Drawing.IDeviceContext,System.String,Color,System.Drawing.Rectangle,Color,System.Windows.Forms.TextFormatFlags)" /> overloads that takes a <see cref="T:System.Windows.Forms.TextFormatFlags" /> parameter. For example, the default behavior of the <see cref="T:System.Windows.Forms.TextRenderer" /> is to add padding to the bounding rectangle of the drawn text to accommodate overhanging glyphs. If you need to draw a line of text without these extra spaces you should use the versions of <see cref="M:System.Windows.Forms.TextRenderer.DrawText(System.Drawing.IDeviceContext,System.String,Color,System.Drawing.Point,Color)" /> and <see cref="M:System.Windows.Forms.TextRenderer.MeasureText(System.Drawing.IDeviceContext,System.String,Color)" /> that take a <see cref="T:System.Drawing.Size" /> and <see cref="T:System.Windows.Forms.TextFormatFlags" /> parameter. For an example, see <see cref="M:System.Windows.Forms.TextRenderer.MeasureText(System.Drawing.IDeviceContext,System.String,Color,System.Drawing.Size,System.Windows.Forms.TextFormatFlags)" />.</returns>
public static Size MeasureText(string text, Font font)
{
if (string.IsNullOrEmpty(text))
{
return Size.Empty;
}
Size result = new Size(19, 19);
return result;
}
}
}
Loading…
Cancel
Save