def delete_cell(row_index = 0, column_index=0, shift=nil)
      validate_workbook
      validate_nonnegative(row_index)
      validate_nonnegative(column_index)

      row = sheet_data[row_index]
      old_cell = row && row[column_index]

      case shift
      when nil then
        row.cells[column_index] = nil if row
      when :left then
        row.delete_cell_shift_left(column_index) if row
      when :up then
        (row_index...(sheet_data.size - 1)).each { |index|
          old_row = sheet_data.rows[index + 1]
          if old_row.nil? then
            sheet_data.rows[index] = nil
          else
            new_row = sheet_data.rows[index] || add_row(index)
            c = new_row.cells[column_index] = old_row.cells[column_index]
            c.row = (index + 1) if c.is_a?(Cell)
          end
        }
      else
        raise 'invalid shift option'
      end

      return old_cell
    end
def delete_cell(row_index = 0, column_index=0, shift=nil)
      validate_workbook
      validate_nonnegative(row_index)
      validate_nonnegative(column_index)

      row = sheet_data[row_index]
      old_cell = row && row[column_index]

      case shift
      when nil then
        row.cells[column_index] = nil if row
      when :left then
        row.delete_cell_shift_left(column_index) if row
      when :up then
        (row_index...(sheet_data.size - 1)).each { |index|
          old_row = sheet_data.rows[index + 1]
          if old_row.nil? then
            sheet_data.rows[index] = nil
          else
            new_row = sheet_data.rows[index] || add_row(index)
            c = new_row.cells[column_index] = old_row.cells[column_index]
            c.row = (index + 1) if c.is_a?(Cell)
          end
        }
      else
        raise 'invalid shift option'
      end

      return old_cell
    end
by default, only sets cell to nil
 if :left is specified, method will shift row contents to the right of the deleted cell to the left
 if :up is specified, method will shift column contents below the deleted cell upward