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