How do I use rubyXL to lock the existing cells in a worksheet but leave all empty cells unlocked? (I don't want to make the user jump through any hoops like requiring him or her to create a new column before entering new data.)
I figured out how to lock existing cells using the technique presented in this StackOverflow post: How can we protect some parts of a sheet using rubyXL? (The basic idea is to (1) Create a new xf, (2) register the new xf with the workbook, (3) set the style_index
of all existing cells to use this xf, then (4) set the WorksheetProtection
for the sheet.)
However, when I do this and open the workbook in Excel, all the empty cells in the worksheet are also locked.
In principle, I need to add an "unlocked" xf to all unused cells; however, since these cells don't exist yet, there is no Cell object to which to set the "unlocked" xf.
There is a way to do this in Excel:
When I follows these steps then examine the worksheet using rubyXL, I see that there are three XL objects:
The existing cells all use style/XL 2. So, I'm thinking that there must be a way to specify that all unused cells in the worksheet default to style/XL 3; but, I don't see how to specify this using rubyXL.
Any ideas?
I figured it out:
require "rubyXL"
require "rubyXL/convenience_methods"
workbook = RubyXL::Workbook.new
sheet = workbook.worksheets.first
# Crate an xf that locks the cell
locked_xf = workbook.cell_xfs.first.dup
locked_xf.protection = RubyXL::Protection.new(
locked: true,
hidden: false,
)
locked_id = workbook.register_new_xf(locked_xf)
# Crate an xf that does not lock the cell
unlocked_xf = workbook.cell_xfs.first.dup
unlocked_xf.protection = RubyXL::Protection.new(
locked: false,
hidden: false,
)
unlocked_id = workbook.register_new_xf(unlocked_xf)
# Create new cells. Lock each one.
(0..5).each do |row|
(0..5).each do |col|
cell = sheet.add_cell(row, col, (row * col).to_s)
cell.style_index = locked_id
end
end
# Create a cell range to cover "all" rows. (Upper bound set at 16384)
range = RubyXL::ColumnRange.new
range.min = 1
range.max = 16384
range.width = 10.83203125 # be sure to set this, otherwise columns aren't visible.
range.style_index = unlocked_id
sheet.cols << range
# Lock the sheet
sheet.sheet_protection = RubyXL::WorksheetProtection.new(
sheet: true,
objects: true,
scenarios: true,
format_cells: true,
format_columns: true,
insert_columns: true,
delete_columns: true,
insert_rows: true,
delete_rows: true
)
workbook.write("lock_test.xlsx")
(I also put a copy of this code here: https://github.com/kurmasz/rubyXL-recipes )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.