@@ -1132,20 +1132,15 @@ private string CreateRowString(DynamicRow dynamicRow, Worksheet worksheet)
11321132 /// <summary>
11331133 /// Method to create the protection string of the passed worksheet
11341134 /// </summary>
1135- /// <param name="sheet">Worksheet to process. </param>
1136- /// <returns>Formatted string with protection statement of the worksheet. </returns>
1135+ /// <param name="sheet">Worksheet to process</param>
1136+ /// <returns>Formatted string with protection statement of the worksheet</returns>
11371137 private string CreateSheetProtectionString ( Worksheet sheet )
11381138 {
11391139 if ( ! sheet . UseSheetProtection )
11401140 {
11411141 return string . Empty ;
11421142 }
11431143 Dictionary < Worksheet . SheetProtectionValue , int > actualLockingValues = new Dictionary < Worksheet . SheetProtectionValue , int > ( ) ;
1144- if ( sheet . SheetProtectionValues . Count == 0 )
1145- {
1146- actualLockingValues . Add ( Worksheet . SheetProtectionValue . selectLockedCells , 1 ) ;
1147- actualLockingValues . Add ( Worksheet . SheetProtectionValue . selectUnlockedCells , 1 ) ;
1148- }
11491144 if ( ! sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . objects ) )
11501145 {
11511146 actualLockingValues . Add ( Worksheet . SheetProtectionValue . objects , 1 ) ;
@@ -1154,46 +1149,80 @@ private string CreateSheetProtectionString(Worksheet sheet)
11541149 {
11551150 actualLockingValues . Add ( Worksheet . SheetProtectionValue . scenarios , 1 ) ;
11561151 }
1157- if ( ! sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . selectLockedCells ) && ! actualLockingValues . ContainsKey ( Worksheet . SheetProtectionValue . selectLockedCells ) )
1152+ bool allowSelectLocked = sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . selectLockedCells ) ;
1153+ bool allowSelectUnlocked = sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . selectUnlockedCells ) ;
1154+ if ( allowSelectLocked && ! allowSelectUnlocked )
1155+ {
1156+ // This shouldn't happen in Excel's UI, but handle it by allowing both
1157+ allowSelectUnlocked = true ;
1158+ }
1159+ if ( ! allowSelectLocked )
11581160 {
11591161 actualLockingValues . Add ( Worksheet . SheetProtectionValue . selectLockedCells , 1 ) ;
11601162 }
1161- if ( ( ! sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . selectUnlockedCells ) || ! sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . selectLockedCells ) ) && ! actualLockingValues . ContainsKey ( Worksheet . SheetProtectionValue . selectUnlockedCells ) )
1163+ if ( ! allowSelectUnlocked )
11621164 {
11631165 actualLockingValues . Add ( Worksheet . SheetProtectionValue . selectUnlockedCells , 1 ) ;
11641166 }
1165- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatCells ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatCells , 0 ) ; }
1166- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatColumns ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatColumns , 0 ) ; }
1167- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatRows ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatRows , 0 ) ; }
1168- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertColumns ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertColumns , 0 ) ; }
1169- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertRows ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertRows , 0 ) ; }
1170- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertHyperlinks ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertHyperlinks , 0 ) ; }
1171- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . deleteColumns ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . deleteColumns , 0 ) ; }
1172- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . deleteRows ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . deleteRows , 0 ) ; }
1173- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . sort ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . sort , 0 ) ; }
1174- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . autoFilter ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . autoFilter , 0 ) ; }
1175- if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . pivotTables ) ) { actualLockingValues . Add ( Worksheet . SheetProtectionValue . pivotTables , 0 ) ; }
1167+ // Explicit permissions (set to 0 when allowed)
1168+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatCells ) )
1169+ {
1170+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatCells , 0 ) ;
1171+ }
1172+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatColumns ) )
1173+ {
1174+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatColumns , 0 ) ;
1175+ }
1176+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . formatRows ) )
1177+ {
1178+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . formatRows , 0 ) ;
1179+ }
1180+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertColumns ) )
1181+ {
1182+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertColumns , 0 ) ;
1183+ }
1184+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertRows ) )
1185+ {
1186+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertRows , 0 ) ;
1187+ }
1188+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . insertHyperlinks ) )
1189+ {
1190+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . insertHyperlinks , 0 ) ;
1191+ }
1192+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . deleteColumns ) )
1193+ {
1194+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . deleteColumns , 0 ) ;
1195+ }
1196+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . deleteRows ) )
1197+ {
1198+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . deleteRows , 0 ) ;
1199+ }
1200+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . sort ) )
1201+ {
1202+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . sort , 0 ) ;
1203+ }
1204+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . autoFilter ) )
1205+ {
1206+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . autoFilter , 0 ) ;
1207+ }
1208+ if ( sheet . SheetProtectionValues . Contains ( Worksheet . SheetProtectionValue . pivotTables ) )
1209+ {
1210+ actualLockingValues . Add ( Worksheet . SheetProtectionValue . pivotTables , 0 ) ;
1211+ }
11761212 StringBuilder sb = new StringBuilder ( ) ;
1177- sb . Append ( "<sheetProtection" ) ;
1213+ sb . Append ( "<sheetProtection sheet=\" 1\" " ) ;
1214+
11781215 string temp ;
11791216 foreach ( KeyValuePair < Worksheet . SheetProtectionValue , int > item in actualLockingValues )
11801217 {
1181- try
1182- {
1183- temp = Enum . GetName ( typeof ( Worksheet . SheetProtectionValue ) , item . Key ) ; // Note! If the enum names differs from the OOXML definitions, this method will cause invalid OOXML entries
1184- sb . Append ( " " ) . Append ( temp ) . Append ( "=\" " ) . Append ( item . Value . ToString ( "G" , culture ) ) . Append ( "\" " ) ;
1185- }
1186- catch
1187- {
1188- // no-op
1189- }
1218+ temp = Enum . GetName ( typeof ( Worksheet . SheetProtectionValue ) , item . Key ) ; // Note! If the enum names differs from the OOXML definitions, this method will cause invalid OOXML entries
1219+ sb . Append ( " " ) . Append ( temp ) . Append ( "=\" " ) . Append ( item . Value . ToString ( "G" , culture ) ) . Append ( "\" " ) ;
11901220 }
1191- if ( ! string . IsNullOrEmpty ( sheet . SheetProtectionPassword ) )
1221+ if ( ! string . IsNullOrEmpty ( sheet . SheetProtectionPasswordHash ) )
11921222 {
1193- string hash = GeneratePasswordHash ( sheet . SheetProtectionPassword ) ;
1194- sb . Append ( " password=\" " ) . Append ( hash ) . Append ( "\" " ) ;
1223+ sb . Append ( " password=\" " ) . Append ( sheet . SheetProtectionPasswordHash ) . Append ( "\" " ) ;
11951224 }
1196- sb . Append ( " sheet= \" 1 \" />" ) ;
1225+ sb . Append ( "/>" ) ;
11971226 return sb . ToString ( ) ;
11981227 }
11991228
@@ -1454,20 +1483,17 @@ private string CreateStyleXfsString()
14541483 alignmentString = sb2 . ToString ( ) ;
14551484 }
14561485
1457- if ( style . CurrentCellXf . Hidden || style . CurrentCellXf . Locked )
1486+ if ( style . CurrentCellXf . Hidden && style . CurrentCellXf . Locked )
14581487 {
1459- if ( style . CurrentCellXf . Hidden && style . CurrentCellXf . Locked )
1460- {
1461- protectionString = "<protection locked=\" 1\" hidden=\" 1\" />" ;
1462- }
1463- else if ( style . CurrentCellXf . Hidden && ! style . CurrentCellXf . Locked )
1464- {
1465- protectionString = "<protection hidden=\" 1\" locked=\" 0\" />" ;
1466- }
1467- else
1468- {
1469- protectionString = "<protection hidden=\" 0\" locked=\" 1\" />" ;
1470- }
1488+ protectionString = "<protection locked=\" 1\" hidden=\" 1\" />" ;
1489+ }
1490+ else if ( style . CurrentCellXf . Hidden && ! style . CurrentCellXf . Locked )
1491+ {
1492+ protectionString = "<protection hidden=\" 1\" locked=\" 0\" />" ;
1493+ }
1494+ else if ( ! style . CurrentCellXf . Hidden && ! style . CurrentCellXf . Locked )
1495+ {
1496+ protectionString = "<protection locked=\" 0\" />" ;
14711497 }
14721498
14731499 sb . Append ( "<xf numFmtId=\" " ) ;
0 commit comments