Skip to content

Commit 3cf14a5

Browse files
authored
Add new function: AddFormControl (#6)
- Update unit test - Add unmanaged type for bool data type fields - Set badge icon color for NuGet package README
1 parent 0f89f75 commit 3cf14a5

File tree

5 files changed

+336
-8
lines changed

5 files changed

+336
-8
lines changed

Excelize.Tests/UnitTest.cs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public void TestStyle()
215215
}
216216

217217
[Fact]
218-
public void TesttreamWriter()
218+
public void TestStreamWriter()
219219
{
220220
var f = Excelize.NewFile();
221221
Assert.Null(
@@ -409,11 +409,95 @@ public void TestAddFormControl()
409409
Assert.Null(
410410
Record.Exception(() =>
411411
{
412+
f.AddFormControl(
413+
"Sheet1",
414+
new FormControl
415+
{
416+
Cell = "A3",
417+
Macro = "Button1_Click",
418+
Width = 140,
419+
Height = 60,
420+
Text = "Button 1\r\n",
421+
Paragraph = new RichTextRun[]
422+
{
423+
new()
424+
{
425+
Font = new Font
426+
{
427+
Bold = true,
428+
Italic = true,
429+
Underline = "single",
430+
Family = "Times New Roman",
431+
Size = 14,
432+
Color = "777777",
433+
},
434+
Text = "C1=A1+B1",
435+
},
436+
},
437+
Type = FormControlType.FormControlButton,
438+
Format = new GraphicOptions
439+
{
440+
PrintObject = true,
441+
Positioning = "absolute",
442+
},
443+
}
444+
);
445+
f.AddFormControl(
446+
"Sheet1",
447+
new FormControl
448+
{
449+
Cell = "A1",
450+
Macro = "Button1_Click",
451+
Text = "Option Button 1",
452+
Type = FormControlType.FormControlOptionButton,
453+
}
454+
);
455+
f.AddFormControl(
456+
"Sheet1",
457+
new FormControl
458+
{
459+
Cell = "B1",
460+
Type = FormControlType.FormControlSpinButton,
461+
Width = 15,
462+
Height = 40,
463+
CurrentVal = 7,
464+
MinVal = 5,
465+
MaxVal = 10,
466+
IncChange = 1,
467+
CellLink = "A1",
468+
}
469+
);
470+
f.AddFormControl(
471+
"Sheet1",
472+
new FormControl
473+
{
474+
Cell = "B3",
475+
Type = FormControlType.FormControlScrollBar,
476+
Width = 140,
477+
Height = 20,
478+
CurrentVal = 50,
479+
MinVal = 10,
480+
MaxVal = 100,
481+
PageChange = 1,
482+
CellLink = "A1",
483+
Horizontally = true,
484+
}
485+
);
486+
f.AddFormControl("Sheet1", null);
412487
f.AddVBAProject(
413488
System.IO.File.ReadAllBytes(
414489
Path.GetFullPath(Path.Combine("..", "..", "..", "vbaProject.bin"))
415490
)
416491
);
492+
})
493+
);
494+
var err = Assert.Throws<RuntimeError>(() =>
495+
f.AddFormControl("SheetN", new FormControl { })
496+
);
497+
Assert.Equal("sheet SheetN does not exist", err.Message);
498+
Assert.Null(
499+
Record.Exception(() =>
500+
{
417501
f.SaveAs("TestAddFormControl.xlsm");
418502
})
419503
);

Excelize/Excelize.cs

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ internal static extern IntPtr AddComment(
117117
ref TypesC.Comment comment
118118
);
119119

120+
[DllImport(
121+
LibraryName,
122+
CallingConvention = CallingConvention.Cdecl,
123+
CharSet = CharSet.Ansi
124+
)]
125+
internal static extern IntPtr AddFormControl(
126+
long fileIdx,
127+
string sheet,
128+
ref TypesC.FormControl options
129+
);
130+
120131
[DllImport(
121132
LibraryName,
122133
CallingConvention = CallingConvention.Cdecl,
@@ -1327,6 +1338,154 @@ public unsafe void AddComment(string sheet, Comment? options = null)
13271338
throw new RuntimeError(err);
13281339
}
13291340

1341+
/// <summary>
1342+
/// AddFormControl provides the method to add form control object in a
1343+
/// worksheet by given worksheet name and form control options.
1344+
/// Supported form control type: button, check box, group box, label,
1345+
/// option button, scroll bar and spinner. If set macro for the form
1346+
/// control, the workbook extension should be XLSM or XLTM. Scroll value
1347+
/// must be between 0 and 30000. Please note that if a cell link is set
1348+
/// for a checkbox form control, Excelize will not assign a value to the
1349+
/// linked cell when the checkbox is checked. To reflect the checkbox
1350+
/// state, please use the <c>SetCellValue</c> function to manually set
1351+
/// the linked cell's value to <c>true</c>.
1352+
/// <example>
1353+
/// </example>
1354+
/// Example 1, add button form control with macro, rich-text, custom
1355+
/// button size, print property on Sheet1!A2, and let the button do not
1356+
/// move or size with cells:
1357+
/// <code>
1358+
/// try
1359+
/// {
1360+
/// f.AddFormControl(
1361+
/// "Sheet1",
1362+
/// new FormControl
1363+
/// {
1364+
/// Cell = "A2",
1365+
/// Macro = "Button1_Click",
1366+
/// Width = 140,
1367+
/// Height = 60,
1368+
/// Text = "Button 1\r\n",
1369+
/// Paragraph = new RichTextRun[]
1370+
/// {
1371+
/// new()
1372+
/// {
1373+
/// Font = new Font
1374+
/// {
1375+
/// Bold = true,
1376+
/// Italic = true,
1377+
/// Underline = "single",
1378+
/// Family = "Times New Roman",
1379+
/// Size = 14,
1380+
/// Color = "777777",
1381+
/// },
1382+
/// Text = "C1=A1+B1",
1383+
/// },
1384+
/// },
1385+
/// Type = FormControlType.FormControlButton,
1386+
/// Format = new GraphicOptions
1387+
/// {
1388+
/// PrintObject = true,
1389+
/// Positioning = "absolute",
1390+
/// },
1391+
/// }
1392+
/// );
1393+
/// }
1394+
/// catch (RuntimeError err)
1395+
/// {
1396+
/// Console.WriteLine(err.Message);
1397+
/// }
1398+
/// </code>
1399+
/// Example 2, add option button form control with checked status and
1400+
/// text on Sheet1!A1:
1401+
/// <code>
1402+
/// try
1403+
/// {
1404+
/// f.AddFormControl(
1405+
/// "Sheet1",
1406+
/// new FormControl
1407+
/// {
1408+
/// Cell = "A1",
1409+
/// Macro = "Button1_Click",
1410+
/// Text = "Option Button 1",
1411+
/// Type = FormControlType.FormControlOptionButton,
1412+
/// }
1413+
/// );
1414+
/// }
1415+
/// catch (RuntimeError err)
1416+
/// {
1417+
/// Console.WriteLine(err.Message);
1418+
/// }
1419+
/// </code>
1420+
/// Example 3, add spin button form control on Sheet1!B1 to increase or
1421+
/// decrease the value of Sheet1!A1:
1422+
/// <code>
1423+
/// try
1424+
/// {
1425+
/// f.AddFormControl(
1426+
/// "Sheet1",
1427+
/// new FormControl
1428+
/// {
1429+
/// Cell = "B1",
1430+
/// Type = FormControlType.FormControlSpinButton,
1431+
/// Width = 15,
1432+
/// Height = 40,
1433+
/// CurrentVal = 7,
1434+
/// MinVal = 5,
1435+
/// MaxVal = 10,
1436+
/// IncChange = 1,
1437+
/// CellLink = "A1",
1438+
/// }
1439+
/// );
1440+
/// }
1441+
/// catch (RuntimeError err)
1442+
/// {
1443+
/// Console.WriteLine(err.Message);
1444+
/// }
1445+
/// </code>
1446+
/// Example 4, add horizontally scroll bar form control on Sheet1!A2 to
1447+
/// change the value of Sheet1!A1 by click the scroll arrows or drag
1448+
/// the scroll box:
1449+
/// <code>
1450+
/// try
1451+
/// {
1452+
/// f.AddFormControl(
1453+
/// "Sheet1",
1454+
/// new FormControl
1455+
/// {
1456+
/// Cell = "A2",
1457+
/// Type = FormControlType.FormControlScrollBar,
1458+
/// Width = 140,
1459+
/// Height = 20,
1460+
/// CurrentVal = 50,
1461+
/// MinVal = 10,
1462+
/// MaxVal = 100,
1463+
/// PageChange = 1,
1464+
/// CellLink = "A1",
1465+
/// Horizontally = true,
1466+
/// }
1467+
/// );
1468+
/// }
1469+
/// catch (RuntimeError err)
1470+
/// {
1471+
/// Console.WriteLine(err.Message);
1472+
/// }
1473+
/// </code>
1474+
/// </summary>
1475+
/// <param name="sheet">The worksheet name</param>
1476+
/// <param name="options">The form control options</param>
1477+
/// <exception cref="RuntimeError">Return None if no error occurred,
1478+
/// otherwise raise a RuntimeError with the message.</exception>
1479+
public unsafe void AddFormControl(string sheet, FormControl? options = null)
1480+
{
1481+
if (options == null)
1482+
return;
1483+
var opts = (TypesC.FormControl)Lib.CsToC(options, new TypesC.FormControl());
1484+
string err = Marshal.PtrToStringAnsi(Lib.AddFormControl(FileIdx, sheet, ref opts));
1485+
if (!string.IsNullOrEmpty(err))
1486+
throw new RuntimeError(err);
1487+
}
1488+
13301489
/// <summary>
13311490
/// Add picture in a sheet by given picture format set (such as offset,
13321491
/// scale, aspect ratio setting and print settings) and file path.

Excelize/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
!["excelize-cs logo"](https://raw.githubusercontent.com/xuri/excelize-cs/main/Excelize/excelize-cs.png)
44

5-
[!["NuGet version"](https://img.shields.io/nuget/v/ExcelizeCs.svg)](https://www.nuget.org/packages/ExcelizeCs)
5+
[!["NuGet version"](https://img.shields.io/nuget/v/ExcelizeCs.svg?color=%23007ec6)](https://www.nuget.org/packages/ExcelizeCs)
66
[!["Build Status"](https://github.com/xuri/excelize-cs/actions/workflows/build.yml/badge.svg)](https://github.com/xuri/excelize-cs/actions/workflows/build.yml)
77
[!["Code Coverage"](https://codecov.io/gh/xuri/excelize-cs/branch/main/graph/badge.svg)](https://codecov.io/gh/xuri/excelize-cs)
88
[!["Licenses"](https://img.shields.io/badge/license-bsd-orange.svg)](https://opensource.org/licenses/BSD-3-Clause)

Excelize/TypesC.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,32 @@ public unsafe struct Comment
189189
public RichTextRun* Paragraph;
190190
}
191191

192+
[StructLayout(LayoutKind.Sequential)]
193+
public unsafe struct FormControl
194+
{
195+
public sbyte* Cell;
196+
public sbyte* Macro;
197+
public uint Width;
198+
public uint Height;
199+
200+
[MarshalAs(UnmanagedType.I1)]
201+
public bool Checked;
202+
public uint CurrentVal;
203+
public uint MinVal;
204+
public uint MaxVal;
205+
public uint IncChange;
206+
public uint PageChange;
207+
208+
[MarshalAs(UnmanagedType.I1)]
209+
public bool Horizontally;
210+
public sbyte* CellLink;
211+
public sbyte* Text;
212+
public int ParagraphLen;
213+
public RichTextRun* Paragraph;
214+
public uint Type;
215+
public GraphicOptions Format;
216+
}
217+
192218
[StructLayout(LayoutKind.Sequential)]
193219
public unsafe struct ChartNumFmt
194220
{
@@ -358,13 +384,22 @@ public unsafe struct Chart
358384
[StructLayout(LayoutKind.Sequential)]
359385
public unsafe struct PivotTableField
360386
{
387+
[MarshalAs(UnmanagedType.I1)]
361388
public bool Compact;
362389
public sbyte* Data;
363390
public sbyte* Name;
391+
392+
[MarshalAs(UnmanagedType.I1)]
364393
public bool Outline;
394+
395+
[MarshalAs(UnmanagedType.I1)]
365396
public bool ShowAll;
397+
398+
[MarshalAs(UnmanagedType.I1)]
366399
public bool InsertBlankRow;
367400
public sbyte* Subtotal;
401+
402+
[MarshalAs(UnmanagedType.I1)]
368403
public bool DefaultSubtotal;
369404
public int NumFmt;
370405
}
@@ -383,21 +418,53 @@ public unsafe struct PivotTableOptions
383418
public PivotTableField* Data;
384419
public int FilterLen;
385420
public PivotTableField* Filter;
421+
422+
[MarshalAs(UnmanagedType.I1)]
386423
public bool RowGrandTotals;
424+
425+
[MarshalAs(UnmanagedType.I1)]
387426
public bool ColGrandTotals;
427+
428+
[MarshalAs(UnmanagedType.I1)]
388429
public bool ShowDrill;
430+
431+
[MarshalAs(UnmanagedType.I1)]
389432
public bool UseAutoFormatting;
433+
434+
[MarshalAs(UnmanagedType.I1)]
390435
public bool PageOverThenDown;
436+
437+
[MarshalAs(UnmanagedType.I1)]
391438
public bool MergeItem;
439+
440+
[MarshalAs(UnmanagedType.I1)]
392441
public bool ClassicLayout;
442+
443+
[MarshalAs(UnmanagedType.I1)]
393444
public bool CompactData;
445+
446+
[MarshalAs(UnmanagedType.I1)]
394447
public bool ShowError;
448+
449+
[MarshalAs(UnmanagedType.I1)]
395450
public bool ShowRowHeaders;
451+
452+
[MarshalAs(UnmanagedType.I1)]
396453
public bool ShowColHeaders;
454+
455+
[MarshalAs(UnmanagedType.I1)]
397456
public bool ShowRowStripes;
457+
458+
[MarshalAs(UnmanagedType.I1)]
398459
public bool ShowColStripes;
460+
461+
[MarshalAs(UnmanagedType.I1)]
399462
public bool ShowLastColumn;
463+
464+
[MarshalAs(UnmanagedType.I1)]
400465
public bool FieldPrintTitles;
466+
467+
[MarshalAs(UnmanagedType.I1)]
401468
public bool ItemPrintTitles;
402469
public sbyte* PivotTableStyleName;
403470
}

0 commit comments

Comments
 (0)