1
+ using System ;
2
+ using DocumentFormat . OpenXml ;
3
+ using DocumentFormat . OpenXml . Packaging ;
4
+ using DocumentFormat . OpenXml . Spreadsheet ;
5
+ using System . Reflection ;
6
+
7
+ namespace Openize . Cells
8
+ {
9
+ /// <summary>
10
+ /// Provides extension methods for managing worksheet display properties and settings.
11
+ /// </summary>
12
+ public static class WorksheetPropertiesExtensions
13
+ {
14
+ /// <summary>
15
+ /// Sets the zoom level for the worksheet view.
16
+ /// </summary>
17
+ /// <param name="worksheet">The worksheet.</param>
18
+ /// <param name="zoomPercentage">The zoom percentage (10-400).</param>
19
+ /// <returns>The worksheet for method chaining.</returns>
20
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
21
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when zoomPercentage is out of valid range (10-400).</exception>
22
+ public static Worksheet SetZoom ( this Worksheet worksheet , int zoomPercentage )
23
+ {
24
+ if ( worksheet == null )
25
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
26
+
27
+ if ( zoomPercentage < 10 || zoomPercentage > 400 )
28
+ throw new ArgumentOutOfRangeException ( nameof ( zoomPercentage ) , "Zoom percentage must be between 10 and 400." ) ;
29
+
30
+ // Just use the worksheet's public API
31
+ var part = GetWorksheetPart ( worksheet ) ;
32
+ if ( part != null )
33
+ {
34
+ // Only update the ZoomScale without touching other elements
35
+ EnsureSheetViewElement ( part ) ;
36
+
37
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
38
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
39
+ if ( sheetView != null )
40
+ {
41
+ sheetView . ZoomScale = ( uint ) zoomPercentage ;
42
+ }
43
+ }
44
+
45
+ return worksheet ;
46
+ }
47
+
48
+ /// <summary>
49
+ /// Sets the default column width for the worksheet.
50
+ /// </summary>
51
+ /// <param name="worksheet">The worksheet.</param>
52
+ /// <param name="width">The default column width in characters.</param>
53
+ /// <returns>The worksheet for method chaining.</returns>
54
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
55
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when width is not positive.</exception>
56
+ public static Worksheet SetDefaultColumnWidth ( this Worksheet worksheet , double width )
57
+ {
58
+ if ( worksheet == null )
59
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
60
+
61
+ if ( width <= 0 )
62
+ throw new ArgumentOutOfRangeException ( nameof ( width ) , "Default column width must be positive." ) ;
63
+
64
+ var part = GetWorksheetPart ( worksheet ) ;
65
+ if ( part != null )
66
+ {
67
+ EnsureSheetFormatPrElement ( part ) ;
68
+
69
+ var sheetFormatPr = part . Worksheet . GetFirstChild < SheetFormatProperties > ( ) ;
70
+ if ( sheetFormatPr != null )
71
+ {
72
+ sheetFormatPr . DefaultColumnWidth = width ;
73
+ }
74
+ }
75
+
76
+ return worksheet ;
77
+ }
78
+
79
+ /// <summary>
80
+ /// Sets the default row height for the worksheet.
81
+ /// </summary>
82
+ /// <param name="worksheet">The worksheet.</param>
83
+ /// <param name="height">The default row height in points.</param>
84
+ /// <returns>The worksheet for method chaining.</returns>
85
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
86
+ /// <exception cref="ArgumentOutOfRangeException">Thrown when height is not positive.</exception>
87
+ public static Worksheet SetDefaultRowHeight ( this Worksheet worksheet , double height )
88
+ {
89
+ if ( worksheet == null )
90
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
91
+
92
+ if ( height <= 0 )
93
+ throw new ArgumentOutOfRangeException ( nameof ( height ) , "Default row height must be positive." ) ;
94
+
95
+ var part = GetWorksheetPart ( worksheet ) ;
96
+ if ( part != null )
97
+ {
98
+ EnsureSheetFormatPrElement ( part ) ;
99
+
100
+ var sheetFormatPr = part . Worksheet . GetFirstChild < SheetFormatProperties > ( ) ;
101
+ if ( sheetFormatPr != null )
102
+ {
103
+ sheetFormatPr . DefaultRowHeight = height ;
104
+ sheetFormatPr . CustomHeight = true ;
105
+ }
106
+ }
107
+
108
+ return worksheet ;
109
+ }
110
+
111
+ /// <summary>
112
+ /// Sets whether to show or hide formulas in the worksheet.
113
+ /// </summary>
114
+ /// <param name="worksheet">The worksheet.</param>
115
+ /// <param name="show">True to show formulas; false to hide formulas.</param>
116
+ /// <returns>The worksheet for method chaining.</returns>
117
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
118
+ public static Worksheet ShowFormulas ( this Worksheet worksheet , bool show )
119
+ {
120
+ if ( worksheet == null )
121
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
122
+
123
+ var part = GetWorksheetPart ( worksheet ) ;
124
+ if ( part != null )
125
+ {
126
+ EnsureSheetViewElement ( part ) ;
127
+
128
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
129
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
130
+ if ( sheetView != null )
131
+ {
132
+ sheetView . ShowFormulas = show ;
133
+ }
134
+ }
135
+
136
+ return worksheet ;
137
+ }
138
+
139
+ /// <summary>
140
+ /// Sets whether to show or hide gridlines in the worksheet.
141
+ /// </summary>
142
+ /// <param name="worksheet">The worksheet.</param>
143
+ /// <param name="show">True to show gridlines; false to hide gridlines.</param>
144
+ /// <returns>The worksheet for method chaining.</returns>
145
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
146
+ public static Worksheet ShowGridlines ( this Worksheet worksheet , bool show )
147
+ {
148
+ if ( worksheet == null )
149
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
150
+
151
+ var part = GetWorksheetPart ( worksheet ) ;
152
+ if ( part != null )
153
+ {
154
+ EnsureSheetViewElement ( part ) ;
155
+
156
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
157
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
158
+ if ( sheetView != null )
159
+ {
160
+ sheetView . ShowGridLines = show ;
161
+ }
162
+ }
163
+
164
+ return worksheet ;
165
+ }
166
+
167
+ /// <summary>
168
+ /// Sets whether to show or hide row and column headers in the worksheet.
169
+ /// </summary>
170
+ /// <param name="worksheet">The worksheet.</param>
171
+ /// <param name="show">True to show headers; false to hide headers.</param>
172
+ /// <returns>The worksheet for method chaining.</returns>
173
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
174
+ public static Worksheet ShowRowColumnHeaders ( this Worksheet worksheet , bool show )
175
+ {
176
+ if ( worksheet == null )
177
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
178
+
179
+ var part = GetWorksheetPart ( worksheet ) ;
180
+ if ( part != null )
181
+ {
182
+ EnsureSheetViewElement ( part ) ;
183
+
184
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
185
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
186
+ if ( sheetView != null )
187
+ {
188
+ sheetView . ShowRowColHeaders = show ;
189
+ }
190
+ }
191
+
192
+ return worksheet ;
193
+ }
194
+
195
+ /// <summary>
196
+ /// Sets whether to show or hide zero values in the worksheet.
197
+ /// </summary>
198
+ /// <param name="worksheet">The worksheet.</param>
199
+ /// <param name="show">True to show zero values; false to hide zero values.</param>
200
+ /// <returns>The worksheet for method chaining.</returns>
201
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
202
+ public static Worksheet ShowZeroValues ( this Worksheet worksheet , bool show )
203
+ {
204
+ if ( worksheet == null )
205
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
206
+
207
+ var part = GetWorksheetPart ( worksheet ) ;
208
+ if ( part != null )
209
+ {
210
+ EnsureSheetViewElement ( part ) ;
211
+
212
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
213
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
214
+ if ( sheetView != null )
215
+ {
216
+ sheetView . ShowZeros = show ;
217
+ }
218
+ }
219
+
220
+ return worksheet ;
221
+ }
222
+
223
+ /// <summary>
224
+ /// Sets whether the worksheet is displayed right-to-left.
225
+ /// </summary>
226
+ /// <param name="worksheet">The worksheet.</param>
227
+ /// <param name="rightToLeft">True for right-to-left display; false for left-to-right display.</param>
228
+ /// <returns>The worksheet for method chaining.</returns>
229
+ /// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
230
+ public static Worksheet SetRightToLeft ( this Worksheet worksheet , bool rightToLeft )
231
+ {
232
+ if ( worksheet == null )
233
+ throw new ArgumentNullException ( nameof ( worksheet ) ) ;
234
+
235
+ var part = GetWorksheetPart ( worksheet ) ;
236
+ if ( part != null )
237
+ {
238
+ EnsureSheetViewElement ( part ) ;
239
+
240
+ var sheetViews = part . Worksheet . GetFirstChild < SheetViews > ( ) ;
241
+ var sheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
242
+ if ( sheetView != null )
243
+ {
244
+ sheetView . RightToLeft = rightToLeft ;
245
+ }
246
+ }
247
+
248
+ return worksheet ;
249
+ }
250
+
251
+ /// <summary>
252
+ /// Ensures that the SheetFormatProperties element exists in the worksheet
253
+ /// </summary>
254
+ private static void EnsureSheetFormatPrElement ( WorksheetPart worksheetPart )
255
+ {
256
+ var worksheet = worksheetPart . Worksheet ;
257
+ var sheetFormatPr = worksheet . GetFirstChild < SheetFormatProperties > ( ) ;
258
+
259
+ if ( sheetFormatPr == null )
260
+ {
261
+ sheetFormatPr = new SheetFormatProperties ( ) ;
262
+
263
+ // Find the correct position for SheetFormatProperties according to the schema
264
+ var sheetViews = worksheet . GetFirstChild < SheetViews > ( ) ;
265
+ if ( sheetViews != null )
266
+ {
267
+ worksheet . InsertAfter ( sheetFormatPr , sheetViews ) ;
268
+ }
269
+ else
270
+ {
271
+ var sheetPr = worksheet . GetFirstChild < SheetProperties > ( ) ;
272
+ if ( sheetPr != null )
273
+ {
274
+ worksheet . InsertAfter ( sheetFormatPr , sheetPr ) ;
275
+ }
276
+ else
277
+ {
278
+ worksheet . PrependChild ( sheetFormatPr ) ;
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ /// <summary>
285
+ /// Ensures that the SheetViews and SheetView elements exist in the worksheet
286
+ /// </summary>
287
+ private static void EnsureSheetViewElement ( WorksheetPart worksheetPart )
288
+ {
289
+ var worksheet = worksheetPart . Worksheet ;
290
+ var sheetViews = worksheet . GetFirstChild < SheetViews > ( ) ;
291
+
292
+ if ( sheetViews == null )
293
+ {
294
+ sheetViews = new SheetViews ( ) ;
295
+
296
+ // Find the correct position for SheetViews according to the schema
297
+ var sheetPr = worksheet . GetFirstChild < SheetProperties > ( ) ;
298
+ if ( sheetPr != null )
299
+ {
300
+ worksheet . InsertAfter ( sheetViews , sheetPr ) ;
301
+ }
302
+ else
303
+ {
304
+ worksheet . PrependChild ( sheetViews ) ;
305
+ }
306
+
307
+ // Add a default SheetView
308
+ var newSheetView = new SheetView { WorkbookViewId = 0 } ;
309
+ sheetViews . Append ( newSheetView ) ;
310
+ }
311
+ else
312
+ {
313
+ var existingSheetView = sheetViews . GetFirstChild < SheetView > ( ) ;
314
+ if ( existingSheetView == null )
315
+ {
316
+ var newSheetView = new SheetView { WorkbookViewId = 0 } ;
317
+ sheetViews . Append ( newSheetView ) ;
318
+ }
319
+ }
320
+ }
321
+
322
+ /// <summary>
323
+ /// Gets the OpenXML worksheet part from a Worksheet object.
324
+ /// </summary>
325
+ private static WorksheetPart GetWorksheetPart ( Worksheet worksheet )
326
+ {
327
+ // Use reflection to access the _worksheetPart field from the Worksheet class
328
+ var fieldInfo = worksheet . GetType ( ) . GetField ( "_worksheetPart" , BindingFlags . NonPublic | BindingFlags . Instance ) ;
329
+ if ( fieldInfo == null )
330
+ return null ;
331
+
332
+ return fieldInfo . GetValue ( worksheet ) as WorksheetPart ;
333
+ }
334
+ }
335
+ }
0 commit comments