view release on metacpan or search on metacpan
+ Added additional page setup methods:
set_zoom()
right_to_left()
hide_zero()
set_custom_color()
set_tab_color()
protect()
+ Added Cell property methods:
set_locked()
set_hidden()
+ Added example programs:
hide_sheet.pl
protection.pl
right_to_left.pl
tab_colors.pl
0.12 2011-02-19
examples/protection.pl view on Meta::CPAN
#
use strict;
use warnings;
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( 'protection.xlsx' );
my $worksheet = $workbook->add_worksheet();
# Create some format objects
my $unlocked = $workbook->add_format( locked => 0 );
my $hidden = $workbook->add_format( hidden => 1 );
# Format the columns
$worksheet->set_column( 'A:A', 45 );
$worksheet->set_selection( 'B3' );
# Protect the worksheet
$worksheet->protect();
# Examples of cell locking and hiding.
$worksheet->write( 'A1', 'Cell B1 is locked. It cannot be edited.' );
$worksheet->write_formula( 'B1', '=1+2', undef, 3 ); # Locked by default.
$worksheet->write( 'A2', 'Cell B2 is unlocked. It can be edited.' );
$worksheet->write_formula( 'B2', '=1+2', $unlocked, 3 );
$worksheet->write( 'A3', "Cell B3 is hidden. The formula isn't visible." );
$worksheet->write_formula( 'B3', '=1+2', $hidden, 3 );
$worksheet->write( 'A5', 'Use Menu->Tools->Protection->Unprotect Sheet' );
$worksheet->write( 'A6', 'to remove the worksheet protection.' );
$workbook->close();
__END__
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
=head2 protect( $password, \%options )
The C<protect()> method is used to protect a worksheet from modification:
$worksheet->protect();
The C<protect()> method also has the effect of enabling a cell's C<locked> and C<hidden> properties if they have been set. A I<locked> cell cannot be edited and this property is on by default for all cells. A I<hidden> cell will display the results o...
See the C<protection.pl> program in the examples directory of the distro for an illustrative example and the C<set_locked> and C<set_hidden> format methods in L</CELL FORMATTING>.
You can optionally add a password to the worksheet protection:
$worksheet->protect( 'drowssap' );
The password should be an ASCII string. Passing the empty string C<''> is the same as turning on protection without a password.
Note, the worksheet level password in Excel provides very weak protection. It does not encrypt your data and is very easy to deactivate. Full workbook encryption is not supported by C<Excel::Writer::XLSX> since it requires a completely different file...
You can specify which worksheet elements you wish to protect by passing a hash_ref with any or all of the following keys:
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
objects => 0,
scenarios => 0,
format_cells => 0,
format_columns => 0,
format_rows => 0,
insert_columns => 0,
insert_rows => 0,
insert_hyperlinks => 0,
delete_columns => 0,
delete_rows => 0,
select_locked_cells => 1,
sort => 0,
autofilter => 0,
pivot_tables => 0,
select_unlocked_cells => 1,
);
The default boolean values are shown above. Individual elements can be protected as follows:
$worksheet->protect( 'drowssap', { insert_rows => 1 } );
For chartsheets the allowable options and default values are:
%options = (
objects => 1,
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
=over
=item * C<number_stored_as_text>: Turn off errors/warnings for numbers stores as text.
=item * C<eval_error>: Turn off errors/warnings for formula errors (such as divide by zero).
=item * C<formula_differs>: Turn off errors/warnings for formulas that differ from surrounding formulas.
=item * C<formula_range>: Turn off errors/warnings for formulas that omit cells in a range.
=item * C<formula_unlocked>: Turn off errors/warnings for unlocked cells that contain formulas.
=item * C<empty_cell_reference>: Turn off errors/warnings for formulas that refer to empty cells.
=item * C<list_data_validation>: Turn off errors/warnings for cells in a table that do not comply with applicable data validation rules.
=item * C<calculated_column>: Turn off errors/warnings for cell formulas that differ from the column formula.
=item * C<two_digit_text_year>: Turn off errors/warnings for formulas that contain a two digit text representation of a year.
=back
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
Bold bold set_bold()
Italic italic set_italic()
Underline underline set_underline()
Strikeout font_strikeout set_font_strikeout()
Super/Subscript font_script set_font_script()
Outline font_outline set_font_outline()
Shadow font_shadow set_font_shadow()
Number Numeric format num_format set_num_format()
Protection Lock cells locked set_locked()
Hide formulas hidden set_hidden()
Alignment Horizontal align align set_align()
Vertical align valign set_align()
Rotation rotation set_rotation()
Text wrap text_wrap set_text_wrap()
Justify last text_justlast set_text_justlast()
Center across center_across set_center_across()
Indentation indent set_indent()
Shrink to fit shrink set_shrink()
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
set_size()
set_color()
set_bold()
set_italic()
set_underline()
set_font_strikeout()
set_font_script()
set_font_outline()
set_font_shadow()
set_num_format()
set_locked()
set_hidden()
set_align()
set_rotation()
set_text_wrap()
set_text_justlast()
set_center_across()
set_indent()
set_shrink()
set_pattern()
set_bg_color()
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
=item * The dollar sign appears as the defined local currency symbol.
=item * The date, time and duration formats appear as the local equivalent date or time format.
=back
=head2 set_locked()
Default state: Cell locking is on
Default action: Turn locking on
Valid args: 0, 1
This property can be used to prevent modification of a cells contents. Following Excel's convention, cell locking is turned on by default. However, it only has an effect if the worksheet has been protected, see the worksheet C<protect()> method.
my $locked = $workbook->add_format();
$locked->set_locked( 1 ); # A non-op
my $unlocked = $workbook->add_format();
$unlocked->set_locked( 0 );
# Enable worksheet protection
$worksheet->protect();
# This cell cannot be edited.
$worksheet->write( 'A1', '=1+2', $locked );
# This cell can be edited.
$worksheet->write( 'A2', '=1+2', $unlocked );
Note: This offers weak protection even with a password, see the note in relation to the C<protect()> method.
=head2 set_hidden()
Default state: Formula hiding is off
Default action: Turn hiding on
lib/Excel/Writer/XLSX.pm view on Meta::CPAN
A filename must be given in the constructor.
=item Can't open filename. It may be in use or protected.
The file cannot be opened for writing. The directory that you are writing to may be protected or the file may be in use by another program.
=item Can't call method "XXX" on an undefined value at someprogram.pl.
On Windows this is usually caused by the file that you are trying to create clashing with a version that is already open and locked by Excel.
=item The file you are trying to open 'file.xls' is in a different format than specified by the file extension.
This warning occurs when you create an XLSX file but give it an xls extension.
=back
lib/Excel/Writer/XLSX/Chartsheet.pm view on Meta::CPAN
$options->{objects} = 0;
}
if ( defined $user_options->{content} ) {
$options->{content} = $user_options->{content};
}
else {
$options->{content} = 1;
}
# If objects and content are off then the chartsheet isn't locked, except
# if it has a password.
if ( $password eq '' && $options->{objects} && !$options->{content} ) {
return;
}
$self->{_chart}->{_protection} = 1;
# Turn off worksheet defaults.
$options->{sheet} = 0;
$options->{scenarios} = 1;
lib/Excel/Writer/XLSX/Examples.pm view on Meta::CPAN
#
use strict;
use warnings;
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( 'protection.xlsx' );
my $worksheet = $workbook->add_worksheet();
# Create some format objects
my $unlocked = $workbook->add_format( locked => 0 );
my $hidden = $workbook->add_format( hidden => 1 );
# Format the columns
$worksheet->set_column( 'A:A', 45 );
$worksheet->set_selection( 'B3' );
# Protect the worksheet
$worksheet->protect();
# Examples of cell locking and hiding.
$worksheet->write( 'A1', 'Cell B1 is locked. It cannot be edited.' );
$worksheet->write_formula( 'B1', '=1+2', undef, 3 ); # Locked by default.
$worksheet->write( 'A2', 'Cell B2 is unlocked. It can be edited.' );
$worksheet->write_formula( 'B2', '=1+2', $unlocked, 3 );
$worksheet->write( 'A3', "Cell B3 is hidden. The formula isn't visible." );
$worksheet->write_formula( 'B3', '=1+2', $hidden, 3 );
$worksheet->write( 'A5', 'Use Menu->Tools->Protection->Unprotect Sheet' );
$worksheet->write( 'A6', 'to remove the worksheet protection.' );
$workbook->close();
__END__
lib/Excel/Writer/XLSX/Format.pm view on Meta::CPAN
_font_family => 2,
_font_charset => 0,
_font_scheme => 'minor',
_font_condense => 0,
_font_extend => 0,
_theme => 0,
_hyperlink => 0,
_xf_id => 0,
_hidden => 0,
_locked => 1,
_text_h_align => 0,
_text_wrap => 0,
_text_v_align => 0,
_text_justlast => 0,
_rotation => 0,
_fg_color => 0x00,
_bg_color => 0x00,
_pattern => 0,
lib/Excel/Writer/XLSX/Format.pm view on Meta::CPAN
# get_protection_properties()
#
# Return properties for an Excel XML <Protection> element.
#
sub get_protection_properties {
my $self = shift;
my @attribs;
push @attribs, 'locked', 0 if !$self->{_locked};
push @attribs, 'hidden', 1 if $self->{_hidden};
return @attribs;
}
###############################################################################
#
# get_format_key()
#
# Returns a unique hash key for the Format object.
#
sub get_format_key {
my $self = shift;
my $key = join ':',
(
$self->get_font_key(), $self->get_border_key,
$self->get_fill_key(), $self->get_alignment_key(),
$self->{_num_format}, $self->{_locked},
$self->{_hidden},
$self->{_quote_prefix},
);
return $key;
}
###############################################################################
#
# get_font_key()
lib/Excel/Writer/XLSX/Package/Styles.pm view on Meta::CPAN
if ( $has_hyperlink ) {
push @attributes, ( 'applyNumberFormat' => 0 );
push @attributes, ( 'applyFill' => 0 );
push @attributes, ( 'applyBorder' => 0 );
push @attributes, ( 'applyAlignment' => 0 );
push @attributes, ( 'applyProtection' => 0 );
$self->xml_start_tag( 'xf', @attributes );
$self->xml_empty_tag( 'alignment', ( 'vertical', 'top' ) );
$self->xml_empty_tag( 'protection', ( 'locked', 0 ) );
$self->xml_end_tag( 'xf' );
}
else {
$self->xml_empty_tag( 'xf', @attributes );
}
}
##############################################################################
#
lib/Excel/Writer/XLSX/Worksheet.pm view on Meta::CPAN
objects => 0,
scenarios => 0,
format_cells => 0,
format_columns => 0,
format_rows => 0,
insert_columns => 0,
insert_rows => 0,
insert_hyperlinks => 0,
delete_columns => 0,
delete_rows => 0,
select_locked_cells => 1,
sort => 0,
autofilter => 0,
pivot_tables => 0,
select_unlocked_cells => 1,
);
# Overwrite the defaults with user specified values.
for my $key ( keys %{$options} ) {
if ( exists $defaults{$key} ) {
$defaults{$key} = $options->{$key};
}
else {
lib/Excel/Writer/XLSX/Worksheet.pm view on Meta::CPAN
my $self = shift;
my $ignores = shift;
# List of valid input parameters.
my %valid_parameter = (
number_stored_as_text => 1,
eval_error => 1,
formula_differs => 1,
formula_range => 1,
formula_unlocked => 1,
empty_cell_reference => 1,
list_data_validation => 1,
calculated_column => 1,
two_digit_text_year => 1,
);
for my $param_key ( keys %$ignores ) {
if ( not exists $valid_parameter{$param_key} ) {
carp "Unknown parameter '$param_key' in ignore_errors()";
return -3;
lib/Excel/Writer/XLSX/Worksheet.pm view on Meta::CPAN
push @attributes, ( "formatCells" => 0 ) if $arg{format_cells};
push @attributes, ( "formatColumns" => 0 ) if $arg{format_columns};
push @attributes, ( "formatRows" => 0 ) if $arg{format_rows};
push @attributes, ( "insertColumns" => 0 ) if $arg{insert_columns};
push @attributes, ( "insertRows" => 0 ) if $arg{insert_rows};
push @attributes, ( "insertHyperlinks" => 0 ) if $arg{insert_hyperlinks};
push @attributes, ( "deleteColumns" => 0 ) if $arg{delete_columns};
push @attributes, ( "deleteRows" => 0 ) if $arg{delete_rows};
push @attributes, ( "selectLockedCells" => 1 )
if !$arg{select_locked_cells};
push @attributes, ( "sort" => 0 ) if $arg{sort};
push @attributes, ( "autoFilter" => 0 ) if $arg{autofilter};
push @attributes, ( "pivotTables" => 0 ) if $arg{pivot_tables};
push @attributes, ( "selectUnlockedCells" => 1 )
if !$arg{select_unlocked_cells};
$self->xml_empty_tag( 'sheetProtection', @attributes );
}
##############################################################################
#
# _write_protected_ranges()
#
lib/Excel/Writer/XLSX/Worksheet.pm view on Meta::CPAN
if ( exists $ignore->{formula_differs} ) {
my $range = $ignore->{formula_differs};
$self->_write_ignored_error( 'formula', $range );
}
if ( exists $ignore->{formula_range} ) {
my $range = $ignore->{formula_range};
$self->_write_ignored_error( 'formulaRange', $range );
}
if ( exists $ignore->{formula_unlocked} ) {
my $range = $ignore->{formula_unlocked};
$self->_write_ignored_error( 'unlockedFormula', $range );
}
if ( exists $ignore->{empty_cell_reference} ) {
my $range = $ignore->{empty_cell_reference};
$self->_write_ignored_error( 'emptyCellReference', $range );
}
if ( exists $ignore->{list_data_validation} ) {
my $range = $ignore->{list_data_validation};
$self->_write_ignored_error( 'listDataValidation', $range );
t/chartsheet/sub_write_sheet_protection.t view on Meta::CPAN
objects => 1,
scenarios => 1,
format_cells => 1,
format_columns => 1,
format_rows => 1,
insert_columns => 1,
insert_rows => 1,
insert_hyperlinks => 1,
delete_columns => 1,
delete_rows => 1,
select_locked_cells => 0,
sort => 1,
autofilter => 1,
pivot_tables => 1,
select_unlocked_cells => 0,
);
$chartsheet = _new_object( \$got, 'Excel::Writer::XLSX::Chartsheet' );
$chartsheet->protect( $password, \%options );
$chartsheet->_write_sheet_protection();
is( $got, $expected, $caption );
t/package/styles/sub_write_xf.t view on Meta::CPAN
$style = _new_style(\$got);
$style->_write_xf( $format );
is( $got, $expected, $caption );
###############################################################################
#
# 33. Test the _write_xf() method. With cell protection.
#
%properties = ( locked => 0 );
$caption = " \tStyles: _write_xf()";
$expected = '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyProtection="1"><protection locked="0"/></xf>';
$format = Excel::Writer::XLSX::Format->new( {}, {}, %properties );
$style = _new_style(\$got);
$style->_write_xf( $format );
is( $got, $expected, $caption );
###############################################################################
t/package/styles/sub_write_xf.t view on Meta::CPAN
$style = _new_style(\$got);
$style->_write_xf( $format );
is( $got, $expected, $caption );
###############################################################################
#
# 35. Test the _write_xf() method. With cell protection.
#
%properties = ( locked => 0, hidden => 1 );
$caption = " \tStyles: _write_xf()";
$expected = '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyProtection="1"><protection locked="0" hidden="1"/></xf>';
$format = Excel::Writer::XLSX::Format->new( {}, {}, %properties );
$style = _new_style(\$got);
$style->_write_xf( $format );
is( $got, $expected, $caption );
###############################################################################
#
# 36. Test the _write_xf() method. With cell protection + align.
#
%properties = ( align => 'right', locked => 0, hidden => 1 );
$caption = " \tStyles: _write_xf()";
$expected = '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" applyAlignment="1" applyProtection="1"><alignment horizontal="right"/><protection locked="0" hidden="1"/></xf>';
$format = Excel::Writer::XLSX::Format->new( {}, {}, %properties );
$style = _new_style(\$got);
$style->_write_xf( $format );
is( $got, $expected, $caption );
__END__
t/regression/format02.t view on Meta::CPAN
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
$worksheet->set_row( 0, 30 );
my $format1 = $workbook->add_format(
font => "Arial",
bold => 1,
locked => 1,
rotation => 0,
align => "left",
valign => "bottom"
);
my $format2 = $workbook->add_format(
font => "Arial",
bold => 1,
locked => 1,
rotation => 90,
align => "center",
valign => "bottom"
);
$worksheet->write( 'A1', 'Foo', $format1 );
$worksheet->write( 'B1', 'Bar', $format2 );
$workbook->close();
t/regression/protect01.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect02.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->protect();
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect03.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->protect('password');
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect04.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->protect();
$worksheet->unprotect_range('A1');
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect05.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->protect();
$worksheet->unprotect_range('=A1');
$worksheet->unprotect_range('$C$1:$C$3');
$worksheet->unprotect_range('G4:I6', 'MyRange');
$worksheet->unprotect_range('K7');
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect06.t view on Meta::CPAN
###############################################################################
#
# Test the a simple Excel::Writer::XLSX file with worksheet protection.
#
use Excel::Writer::XLSX;
my $workbook = Excel::Writer::XLSX->new( $got_filename );
my $worksheet = $workbook->add_worksheet();
my $unlocked = $workbook->add_format( locked => 0, hidden => 0 );
my $hidden = $workbook->add_format( locked => 0, hidden => 1 );
$worksheet->protect();
$worksheet->unprotect_range('A1', undef, 'password');
$worksheet->unprotect_range('C1:C3');
$worksheet->unprotect_range('G4:I6', 'MyRange');
$worksheet->unprotect_range('K7', undef, 'foobar');
$worksheet->write( 'A1', 1 );
$worksheet->write( 'A2', 2, $unlocked );
$worksheet->write( 'A3', 3, $hidden );
$workbook->close();
###############################################################################
#
# Compare the generated and existing Excel files.
#
t/regression/protect08.t view on Meta::CPAN
objects => 1,
scenarios => 1,
format_cells => 1,
format_columns => 1,
format_rows => 1,
insert_columns => 1,
insert_rows => 1,
insert_hyperlinks => 1,
delete_columns => 1,
delete_rows => 1,
select_locked_cells => 0,
sort => 1,
autofilter => 1,
pivot_tables => 1,
select_unlocked_cells => 0,
);
$worksheet->protect( "", \%options );
$workbook->close();
###############################################################################
t/worksheet/sub_write_sheet_protection.t view on Meta::CPAN
###############################################################################
#
# 3. Test the _write_sheet_protection() method.
#
$caption = " \tWorksheet: _write_sheet_protection()";
$expected = '<sheetProtection sheet="1" objects="1" scenarios="1" selectLockedCells="1"/>';
$password = '';
%options = ( select_locked_cells => 0 );
$worksheet = _new_worksheet(\$got);
$worksheet->protect( $password, \%options );
$worksheet->_write_sheet_protection();
is( $got, $expected, $caption );
###############################################################################
t/worksheet/sub_write_sheet_protection.t view on Meta::CPAN
$worksheet->_write_sheet_protection();
is( $got, $expected, $caption );
###############################################################################
#
# 17. Test the _write_sheet_protection() method.
#
$caption = " \tWorksheet: _write_sheet_protection()";
$expected = '<sheetProtection sheet="1" objects="1" scenarios="1" formatCells="0" selectLockedCells="1" selectUnlockedCells="1"/>';
$password = '';
%options = ( format_cells => 1, select_locked_cells => 0, select_unlocked_cells => 0 );
$worksheet = _new_worksheet(\$got);
$worksheet->protect( $password, \%options );
$worksheet->_write_sheet_protection();
is( $got, $expected, $caption );
###############################################################################
#
# 18. Test the _write_sheet_protection() method.
#
$caption = " \tWorksheet: _write_sheet_protection()";
$expected = '<sheetProtection password="996B" sheet="1" formatCells="0" formatColumns="0" formatRows="0" insertColumns="0" insertRows="0" insertHyperlinks="0" deleteColumns="0" deleteRows="0" selectLockedCells="1" sort="0" autoFilter="0" pivotTables=...
$password = 'drowssap';
%options = (
objects => 1,
scenarios => 1,
format_cells => 1,
format_columns => 1,
format_rows => 1,
insert_columns => 1,
insert_rows => 1,
insert_hyperlinks => 1,
delete_columns => 1,
delete_rows => 1,
select_locked_cells => 0,
sort => 1,
autofilter => 1,
pivot_tables => 1,
select_unlocked_cells => 0,
);
$worksheet = _new_worksheet(\$got);
$worksheet->protect( $password, \%options );
$worksheet->_write_sheet_protection();
is( $got, $expected, $caption );