Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Manage rows like an Excel
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace LikeExcel {
class Program {
static void Main() {
}
}
static class Excel {
internal const ulong HiddenRowMask = 0x2000;
internal const ushort CustomHeightMask = 0x4000;
internal const ushort DefaultHeightMask = 0x8000;
internal const int MaxRowsCountInGroup = 16;
public static ushort GetRowHeight(int rowIndex, SheetLayoutInfo sheetLayoutInfo) {
ushort defaultHeight = (ushort) sheetLayoutInfo.DefaultFullRowHeightMul4;
if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault)
return defaultHeight;
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return defaultHeight;
RowHeightInfo rowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex);
if (rowHeightInfo == null)
return defaultHeight;
ushort result = 0;
if ((rowHeightInfo.Flags & HiddenRowMask) == 0)
result = rowHeightInfo.Value;
if ((rowHeightInfo.Flags & CustomHeightMask) == 0) {
result |= DefaultHeightMask;
}
return result;
}
public static void SetRowHeight(int rowIndex, ushort newRowHeight, ushort flags, SheetLayoutInfo sheetLayoutInfo) {
sheetLayoutInfo.MaxRowIndexNonDefault = Math.Max(sheetLayoutInfo.MaxRowIndexNonDefault, rowIndex + 1);
sheetLayoutInfo.MinRowIndexNonDefault = Math.Min(sheetLayoutInfo.MinRowIndexNonDefault, rowIndex);
int realGroupIndex = rowIndex >> 4;
if (sheetLayoutInfo.RowsGroups.Count == 0) {
sheetLayoutInfo.RowsGroups.Add(null);
sheetLayoutInfo.GroupIndexDelta = -realGroupIndex;
}
else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex < 0) {
int bucketSize = -(sheetLayoutInfo.GroupIndexDelta + realGroupIndex);
sheetLayoutInfo.RowsGroups.InsertRange(0, new RowsGroupInfo[bucketSize]);
sheetLayoutInfo.GroupIndexDelta = -realGroupIndex;
}
else if (sheetLayoutInfo.GroupIndexDelta + realGroupIndex >= sheetLayoutInfo.RowsGroups.Count) {
int bucketSize = sheetLayoutInfo.GroupIndexDelta + realGroupIndex - sheetLayoutInfo.RowsGroups.Count + 1;
sheetLayoutInfo.RowsGroups.AddRange(new RowsGroupInfo[bucketSize]);
}
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex];
if (rowsGroupInfo == null) {
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + realGroupIndex] = rowsGroupInfo;
}
int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF];
RowHeightInfo rowHeightInfo;
if (rowInfoIndex == -1) {
rowHeightInfo = new RowHeightInfo();
rowsGroupInfo.HeightInfos.Add(rowHeightInfo);
rowsGroupInfo.Indices[rowIndex & 0xF] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
rowHeightInfo = rowsGroupInfo.HeightInfos[rowInfoIndex];
}
rowHeightInfo.Value = newRowHeight;
rowHeightInfo.Flags = flags;
}
static RowHeightInfo GetRowHeightCore(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex < sheetLayoutInfo.MinRowIndexNonDefault || rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return null;
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[sheetLayoutInfo.GroupIndexDelta + (rowIndex >> 4)];
if (rowsGroupInfo == null)
return null;
int rowInfoIndex = rowsGroupInfo.Indices[rowIndex & 0xF];
return rowInfoIndex != -1 ? rowsGroupInfo.HeightInfos[rowInfoIndex] : null;
}
public static void InsertRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return;
RowHeightInfo etalonRowHeightInfo = GetRowHeightCore(sheetLayoutInfo, rowIndex);
RowHeightInfo newRowHeightInfo = etalonRowHeightInfo != null ?
etalonRowHeightInfo.Clone() :
CreateDefaultRowHeight(sheetLayoutInfo);
int realGroupIndex = (rowIndex + 1) >> 4;
int newRowInGroupIndex = (rowIndex + 1) & 0xF;
int groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta;
for (; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) {
if (groupIndex < 0)
continue;
if (groupIndex == SheetLayoutInfo.MaxGroupsCount)
break;
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex];
if (rowsGroupInfo == null) {
if ((newRowHeightInfo.Flags & CustomHeightMask) == 0)
continue;
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo;
}
int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex];
RowHeightInfo lastRowHeightInGroup;
if (rowInfoIndex == -1 || rowsGroupInfo.HeightInfos.Count < MaxRowsCountInGroup) {
int lastRowIndexInGroup = ((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + MaxRowsCountInGroup - 1;
lastRowHeightInGroup = GetRowHeightCore(sheetLayoutInfo, lastRowIndexInGroup);
Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, MaxRowsCountInGroup - 1 - newRowInGroupIndex);
rowsGroupInfo.HeightInfos.Add(newRowHeightInfo);
rowsGroupInfo.Indices[newRowInGroupIndex] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
int lastIndex = rowsGroupInfo.Indices[MaxRowsCountInGroup - 1];
lastRowHeightInGroup = rowsGroupInfo.HeightInfos[lastIndex];
Array.Copy(rowsGroupInfo.Indices, newRowInGroupIndex, rowsGroupInfo.Indices, newRowInGroupIndex + 1, MaxRowsCountInGroup - 1 - newRowInGroupIndex);
rowsGroupInfo.HeightInfos[lastIndex] = newRowHeightInfo;
rowsGroupInfo.Indices[newRowInGroupIndex] = lastIndex;
}
newRowHeightInfo = lastRowHeightInGroup ?? CreateDefaultRowHeight(sheetLayoutInfo);
}
if ((newRowHeightInfo.Flags & CustomHeightMask) != 0 && groupIndex != SheetLayoutInfo.MaxGroupsCount) {
SetRowHeight(((groupIndex - sheetLayoutInfo.GroupIndexDelta) << 4) + newRowInGroupIndex, newRowHeightInfo.Value, newRowHeightInfo.Flags, sheetLayoutInfo);
}
else {
sheetLayoutInfo.MaxRowIndexNonDefault = Math.Min(sheetLayoutInfo.MaxRowIndexNonDefault + 1, SheetLayoutInfo.MaxRowsCount);
}
}
static RowHeightInfo CreateDefaultRowHeight(SheetLayoutInfo sheetLayoutInfo) {
return new RowHeightInfo {Flags = 0, Value = (ushort) sheetLayoutInfo.DefaultFullRowHeightMul4};
}
public static void RemoveRow(SheetLayoutInfo sheetLayoutInfo, int rowIndex) {
if (rowIndex >= sheetLayoutInfo.MaxRowIndexNonDefault)
return;
int realGroupIndex = rowIndex >> 4;
int newRowInGroupIndex = rowIndex & 0xF;
int groupIndex;
for (groupIndex = realGroupIndex + sheetLayoutInfo.GroupIndexDelta; groupIndex < sheetLayoutInfo.RowsGroups.Count; groupIndex++, newRowInGroupIndex = 0) {
if (groupIndex < -1)
continue;
if (groupIndex == -1) {
sheetLayoutInfo.RowsGroups.Insert(0, null);
sheetLayoutInfo.GroupIndexDelta++;
groupIndex = 0;
}
if (groupIndex == SheetLayoutInfo.MaxGroupsCount)
break;
var newRowHeightInfo = groupIndex == SheetLayoutInfo.MaxGroupsCount - 1 ?
null :
GetRowHeightCore(sheetLayoutInfo, (groupIndex - sheetLayoutInfo.GroupIndexDelta + 1) << 4);
RowsGroupInfo rowsGroupInfo = sheetLayoutInfo.RowsGroups[groupIndex];
if (rowsGroupInfo == null) {
if (newRowHeightInfo == null || (newRowHeightInfo.Flags & CustomHeightMask) == 0)
continue;
rowsGroupInfo = new RowsGroupInfo();
sheetLayoutInfo.RowsGroups[groupIndex] = rowsGroupInfo;
}
if (newRowHeightInfo == null) {
newRowHeightInfo = CreateDefaultRowHeight(sheetLayoutInfo);
}
int rowInfoIndex = rowsGroupInfo.Indices[newRowInGroupIndex];
if (rowInfoIndex == -1) {
for (int i = newRowInGroupIndex; i < MaxRowsCountInGroup - 1; i++) {
rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1];
}
rowsGroupInfo.HeightInfos.Add(newRowHeightInfo);
rowsGroupInfo.Indices[MaxRowsCountInGroup - 1] = rowsGroupInfo.HeightInfos.Count - 1;
}
else {
for(int i = newRowInGroupIndex; i < rowsGroupInfo.HeightInfos.Count - 1; i++) {
rowsGroupInfo.Indices[i] = rowsGroupInfo.Indices[i + 1];
}
rowsGroupInfo.Indices[rowsGroupInfo.HeightInfos.Count - 1] = rowInfoIndex;
rowsGroupInfo.HeightInfos[rowInfoIndex] = newRowHeightInfo;
}
}
if(rowIndex <= sheetLayoutInfo.MinRowIndexNonDefault) {
sheetLayoutInfo.MinRowIndexNonDefault = Math.Max(sheetLayoutInfo.MinRowIndexNonDefault - 1, 0);
}
}
}
class RowHeightInfo {
public ushort Value { get; set; }
public ushort Flags { get; set; }
public override string ToString() {
return $"Value: {Value} Flags {Flags:X4}";
}
public RowHeightInfo Clone() {
return new RowHeightInfo {Value = Value, Flags = Flags};
}
}
class RowsGroupInfo {
public int[] Indices { get; }
public List<RowHeightInfo> HeightInfos { get; }
public RowsGroupInfo() {
Indices = new int[Excel.MaxRowsCountInGroup];
HeightInfos = new List<RowHeightInfo>();
for (int i = 0; i < Excel.MaxRowsCountInGroup; i++) {
Indices[i] = -1;
}
}
}
class SheetLayoutInfo {
internal const int MaxRowsCount = 1048576;
internal const int MaxGroupsCount = 65536;
public int MinRowIndexNonDefault { get; set; }
public int DefaultFullRowHeightMul4 { get; set; }
public int DefaultRowDelta2 { get; set; }
public int MaxRowIndexNonDefault { get; set; }
public int GroupIndexDelta { get; set; }
public List<RowsGroupInfo> RowsGroups { get; }
public SheetLayoutInfo() {
RowsGroups = new List<RowsGroupInfo>();
MinRowIndexNonDefault = MaxRowsCount;
}
}
[TestFixture]
public class Tests {
SheetLayoutInfo SheetLayoutInfo { get; set; }
[SetUp]
public void SetUp() {
SheetLayoutInfo = new SheetLayoutInfo();
SheetLayoutInfo.DefaultFullRowHeightMul4 = 0x50;
SheetLayoutInfo.DefaultRowDelta2 = 5;
}
[TearDown]
public void TearDown() {
SheetLayoutInfo = null;
}
[Test]
public void FullSetRowHeightTest() {
Excel.SetRowHeight(16 * 5 + 2, 244, 0x4005, SheetLayoutInfo);
Assert.AreEqual(16 * 5 + 2, SheetLayoutInfo.MinRowIndexNonDefault);
Assert.AreEqual(16 * 5 + 2 + 1, SheetLayoutInfo.MaxRowIndexNonDefault);
Assert.AreEqual(-5, SheetLayoutInfo.GroupIndexDelta);
Assert.AreEqual(1, SheetLayoutInfo.RowsGroups.Count);
Assert.AreEqual(1, SheetLayoutInfo.RowsGroups[0].HeightInfos.Count);
Assert.AreEqual(0, SheetLayoutInfo.RowsGroups[0].Indices[2]);
Assert.AreEqual(244, SheetLayoutInfo.RowsGroups[0].HeightInfos[0].Value);
Assert.AreEqual(0x4005, SheetLayoutInfo.RowsGroups[0].HeightInfos[0].Flags);
Assert.AreEqual(244, Excel.GetRowHeight(16 * 5 + 2, SheetLayoutInfo));
}
[Test]
public void SetSeveralRowHeightTest() {
Excel.SetRowHeight(16 * 5 + 2, 100, 0x4005, SheetLayoutInfo);
Excel.SetRowHeight(16 * 7 + 2, 110, 0x4005, SheetLayoutInfo);
Excel.SetRowHeight(23, 120, 0x4005, SheetLayoutInfo);
Excel.SetRowHeight(20, 130, 0x4005, SheetLayoutInfo);
Excel.SetRowHeight(0, 140, 0x4005, SheetLayoutInfo);
Assert.AreEqual(100, Excel.GetRowHeight(16 * 5 + 2, SheetLayoutInfo));
Assert.AreEqual(110, Excel.GetRowHeight(16 * 7 + 2, SheetLayoutInfo));
Assert.AreEqual(120, Excel.GetRowHeight(23, SheetLayoutInfo));
Assert.AreEqual(130, Excel.GetRowHeight(20, SheetLayoutInfo));
Assert.AreEqual(140, Excel.GetRowHeight(0, SheetLayoutInfo));
}
static RowsGroupInfo CreateGroupHelper(int[] indices, int[] rowsHeight) {
RowsGroupInfo result = new RowsGroupInfo();
Array.Copy(indices, result.Indices, 16);
foreach (int rowHeight in rowsHeight) {
result.HeightInfos.Add(new RowHeightInfo {Flags = Excel.CustomHeightMask, Value = (ushort) rowHeight});
}
return result;
}
static void CompareGroupsHelper(RowsGroupInfo rowsGroup, int[] indices, int[] rowHeights) {
Assert.IsNotNull(rowsGroup);
Assert.AreEqual(16, indices.Length);
for (int i = 0; i < 16; i++) {
Assert.AreEqual(rowsGroup.Indices[i], indices[i]);
}
Assert.AreEqual(rowHeights.Length, rowsGroup.HeightInfos.Count);
for (int i = 0; i < rowHeights.Length; i++) {
Assert.AreEqual(rowHeights[i], rowsGroup.HeightInfos[i].Value);
}
}
[Test]
public void InsertRowTest() {
SheetLayoutInfo.GroupIndexDelta = -1;
SheetLayoutInfo.MinRowIndexNonDefault = 16;
SheetLayoutInfo.MaxRowIndexNonDefault = 64;
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x0E, 0x04, 0x07, 0x00, 0x05, 0x0A, 0x09, 0x0F, 0x03, 0x06, 0x08, 0x0D, 0x01, 0x0B, 0x0C, 0x02},
new[] {0x05, 0x2B, 0x35, 0x45, 0x4B, 0x50, 0x5B, 0x6B, 0x7B, 0x8B, 0xA5, 0xAB, 0xB0, 0xB5, 0xE0, 0x100}
)
);
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x06, 0x02, 0x0E, 0x09, 0x01, 0x07, 0x0F, 0x0C, 0x00, 0x0A, 0x04, 0x0B, 0x03, 0x08, 0x0D, 0x05},
new[] {0x10, 0x15, 0x20, 0x25, 0x30, 0x75, 0x85, 0x90, 0x9B, 0xA0, 0xC5, 0xCB, 0xD0, 0xD5, 0xE5, 0xF0}
)
);
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x0C, 0x08, 0x0E, 0x07, 0x0A, 0x01, 0x06, 0x0F, 0x09, 0x0D, 0x00, 0x05, 0x0B, 0x02, 0x04, 0x03},
new[] {0x0B, 0x1B, 0x3B, 0x40, 0x55, 0x60, 0x65, 0x70, 0x80, 0x95, 0xBB, 0xC0, 0xDB, 0xEB, 0xF5, 0xFB}
)
);
Excel.InsertRow(SheetLayoutInfo, 38);
Assert.AreEqual(16, SheetLayoutInfo.MinRowIndexNonDefault);
Assert.AreEqual(65, SheetLayoutInfo.MaxRowIndexNonDefault);
Assert.AreEqual(4, SheetLayoutInfo.RowsGroups.Count);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[0],
new[] {0x0E, 0x04, 0x07, 0x00, 0x05, 0x0A, 0x09, 0x0F, 0x03, 0x06, 0x08, 0x0D, 0x01, 0x0B, 0x0C, 0x02},
new[] {0x05, 0x2B, 0x35, 0x45, 0x4B, 0x50, 0x5B, 0x6B, 0x7B, 0x8B, 0xA5, 0xAB, 0xB0, 0xB5, 0xE0, 0x100}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[1],
new[] {0x06, 0x02, 0x0E, 0x09, 0x01, 0x07, 0x0F, 0x05, 0x0C, 0x00, 0x0A, 0x04, 0x0B, 0x03, 0x08, 0x0D},
new[] {0x10, 0x15, 0x20, 0x25, 0x30, 0xF0, 0x85, 0x90, 0x9B, 0xA0, 0xC5, 0xCB, 0xD0, 0xD5, 0xE5, 0xF0}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[2],
new[] {0x03, 0x0C, 0x08, 0x0E, 0x07, 0x0A, 0x01, 0x06, 0x0F, 0x09, 0x0D, 0x00, 0x05, 0x0B, 0x02, 0x04},
new[] {0x0B, 0x1B, 0x3B, 0x75, 0x55, 0x60, 0x65, 0x70, 0x80, 0x95, 0xBB, 0xC0, 0xDB, 0xEB, 0xF5, 0xFB}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[3],
new[] {0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
new[] {0x40}
);
}
[Test]
public void InsertRowBeforeNonDefaultTest() {
Excel.SetRowHeight(100, 100, Excel.CustomHeightMask, SheetLayoutInfo);
Excel.InsertRow(SheetLayoutInfo, 50);
Assert.AreEqual(SheetLayoutInfo.DefaultFullRowHeightMul4, Excel.GetRowHeight(100, SheetLayoutInfo));
Assert.AreEqual(100, Excel.GetRowHeight(101, SheetLayoutInfo));
}
[Test]
public void RemoveRowTest() {
SheetLayoutInfo.GroupIndexDelta = -1;
SheetLayoutInfo.MinRowIndexNonDefault = 16;
SheetLayoutInfo.MaxRowIndexNonDefault = 65;
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x0E, 0x04, 0x07, 0x00, 0x05, 0x0A, 0x09, 0x0F, 0x03, 0x06, 0x08, 0x0D, 0x01, 0x0B, 0x0C, 0x02},
new[] {0x05, 0x2B, 0x35, 0x45, 0x4B, 0x50, 0x5B, 0x6B, 0x7B, 0x8B, 0xA5, 0xAB, 0xB0, 0xB5, 0xE0, 0x100}
)
);
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x06, 0x02, 0x0E, 0x09, 0x01, 0x07, 0x0F, 0x05, 0x0C, 0x00, 0x0A, 0x04, 0x0B, 0x03, 0x08, 0x0D},
new[] {0x10, 0x15, 0x20, 0x25, 0x30, 0xF0, 0x85, 0x90, 0x9B, 0xA0, 0xC5, 0xCB, 0xD0, 0xD5, 0xE5, 0xF0}
)
);
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x03, 0x0C, 0x08, 0x0E, 0x07, 0x0A, 0x01, 0x06, 0x0F, 0x09, 0x0D, 0x00, 0x05, 0x0B, 0x02, 0x04},
new[] {0x0B, 0x1B, 0x3B, 0x75, 0x55, 0x60, 0x65, 0x70, 0x80, 0x95, 0xBB, 0xC0, 0xDB, 0xEB, 0xF5, 0xFB}
)
);
SheetLayoutInfo.RowsGroups.Add(
CreateGroupHelper(
new[] {0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
new[] {0x40}
)
);
Excel.RemoveRow(SheetLayoutInfo, 29);
Assert.AreEqual(16, SheetLayoutInfo.MinRowIndexNonDefault);
Assert.AreEqual(65, SheetLayoutInfo.MaxRowIndexNonDefault);
Assert.AreEqual(4, SheetLayoutInfo.RowsGroups.Count);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[0],
new[] {0x0E, 0x04, 0x07, 0x00, 0x05, 0x0A, 0x09, 0x0F, 0x03, 0x06, 0x08, 0x0D, 0x01, 0x0C, 0x02, 0x0B},
new[] {0x05, 0x2B, 0x35, 0x45, 0x4B, 0x50, 0x5B, 0x6B, 0x7B, 0x8B, 0xA5, 0x85, 0xB0, 0xB5, 0xE0, 0x100}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[1],
new[] {0x02, 0x0E, 0x09, 0x01, 0x07, 0x0F, 0x05, 0x0C, 0x00, 0x0A, 0x04, 0x0B, 0x03, 0x08, 0x0D, 0x06},
new[] {0x10, 0x15, 0x20, 0x25, 0x30, 0xF0, 0x75, 0x90, 0x9B, 0xA0, 0xC5, 0xCB, 0xD0, 0xD5, 0xE5, 0xF0}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[2],
new[] {0x0C, 0x08, 0x0E, 0x07, 0x0A, 0x01, 0x06, 0x0F, 0x09, 0x0D, 0x00, 0x05, 0x0B, 0x02, 0x04, 0x03},
new[] {0x0B, 0x1B, 0x3B, 0x40, 0x55, 0x60, 0x65, 0x70, 0x80, 0x95, 0xBB, 0xC0, 0xDB, 0xEB, 0xF5, 0xFB}
);
CompareGroupsHelper(
SheetLayoutInfo.RowsGroups[3],
new[] {0x00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
new[] {0x50}
);
}
[Test]
public void RemoveRowBeforeNonDefaultTest() {
Excel.SetRowHeight(100, 100, Excel.CustomHeightMask, SheetLayoutInfo);
Excel.RemoveRow(SheetLayoutInfo, 50);
Assert.AreEqual(SheetLayoutInfo.DefaultFullRowHeightMul4, Excel.GetRowHeight(100, SheetLayoutInfo));
Assert.AreEqual(100, Excel.GetRowHeight(99, SheetLayoutInfo));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment