RubyXLで起きたトラブルまとめ

# 概要
現在、テンプレートのxlsxファイルを元に、新しくcellを追加したり、既存のcellをコピーしたりしながらxlsxファイルを生成するプロジェクトを担当しています。

技術的にはRubyXLが使われているのですが、そこでなんども想定外の挙動に見舞われました・・・。
英語・日本語共に検索しても全く情報が出てこず苦労したので、ぶち当たった問題についてまとめていきたいと思います。

# 問題1. add_cellしたcellに`change_font_name`が効かない
## 内容
このように`add_cell`でセルを追加し、`change_font_name`でフォント名を変更したとします。

```ruby
book[0].add_cell(0, 0, 'セルを追加します。')
book[0][0][0].change_font_name('ＭＳ 明朝')
```

cellのfont_nameを見たら、しっかり変更されています。

```ruby
book[0][0][0].font_name
-> "ＭＳ 明朝"
```

しかし実際にexcelファイルを開くと、フォントが変更されていません・・・。

## 解決法
`font.schema`を`nil`にすれば動作しました。

```ruby
book[0].map { |row| row&.cells&.map { |cell| cell&.change_font_name('ＭＳ 明朝') } } |
book.fonts.map { |font| font.scheme = nil } |
```

# 問題2. 既存のCellのフォントカラーから取得し、他のセルに適用できない
fill_color、font_color共に正しく取得からの適用ができないことが多々あります。

```ruby
new_cell = sheet.add_cell(x, y, cell)
new_cell.change_fill(cell.fill_color)
new_cell.change_font_color(cell.font_color)
```

## 原因1 Theme Colorは`font_color`や`fill_color`だとnilになる
Theme Colorsで設定した色はCellのfont_colorやfill_colorでnilになってしまいます・・・
<img width="195" alt="Screen Shot 2562-03-04 at 17.45.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/74964/212569c8-ce2f-2aa4-2650-b54a252d0701.png">

```ruby
pry(main)> book.fonts.map(&:color)
=> [#<RubyXL::Color:0x007fbb8dd87ea8 @auto=nil, @indexed=nil, @local_namespaces=[], @rgb=nil, @theme=1, @tint=nil>,
...
```

## 原因2 それ以外の方法で指定した色は`RubyXL::Color`で弾かれる
それ以外の方法で色を指定すると、8桁のカラーコード(ARGB)で入れられます。

```ruby
pry(main)> book[1].map{|row| row.cells.map{|cell| cell&.font_color}}
=> [["FFFFFFFF", "FFFFFFFF"],
 ["FFFFFFFF", "FFFFFFFF"],
...
```

これが`RubyXL::Color`のvalidationに引っかかってしまうため、`change_font_color(cell.font_color)`などでエラーになってしまいます。

```rubyXL/objects/color.rb
module RubyXL
  class Color < OOXMLObject
    COLOR_REGEXP = /\A([a-f]|[A-F]|[0-9]){6}\Z/

    ...

    def self.validate_color(color)
      if color =~ COLOR_REGEXP
        return true
      else
        raise 'invalid color'
      end
    end
  ...
```

##

# 問題3 既存のExcelファイルをparseし、writeしたときに、Excelファイルが壊れる
Excelファイルを開いて、保存したときに壊れることがあります。

```ruby
parser = RubyXL::Parser.parse('test.xlsx')
parser.write # -> test.xlsxが壊れる
```

## 原因1 チェックボックスがあると壊れる
こういうのがあると壊れます。
<img width="39" alt="Screen Shot 2562-03-04 at 18.05.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/74964/4f65483f-6250-6cb3-f45c-4b7ad42442e3.png">

## 原因2 DefinedNameの中身次第で壊れる
不要なDefinedNameは極力消しましょう。
<img width="470" alt="Screen Shot 2562-03-04 at 18.06.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/74964/2d2143d1-d416-1927-3b77-900046770e2c.png">

ただエクセル上では見えないDefinedNameがあったりするので注意です。
（見る方法はあるかもしれませんが・・・）

## 原因3 merge_cellsされてる箇所をmerge_cellsする
当たり前といえば当たり前ですが、自動化してると気づかずやってしまうことがあります。

# 問題4 印刷範囲を変えたい
defined_nameで指定されてるため、あれば既存のシートの中身を修正、なければdefinedNameを追加します。

```ruby
book.defined_names.each do |defined_name|
  defined_name.reference = "Sheet1!$A$1:$B$#{@parser.book[1].count}" if defined_name.reference.start_with?('Sheet1')
end
```

# 問題5 日付を`change_contents`しても適用されない
過去記事参照) [RubyXLで日付をchange_contentsしても適用されない問題](https://qiita.com/dorarep/items/8bae247e871fbdf4cde5)

# 問題6 `cell.change_horizontal_alignment`, `cell.change_vertical_alignment`が効かない
原因調査中

# 問題7 ページごとの印刷範囲を変えたい
方法調査中

# おわりに
ExcelのバージョンやOSなどにも依存するかと思いますが、RubyXLで起きたトラブルについてまとめてみました。
ただでさえ業務がらつかわないのに、ブラックボックスな他社ツールに依存した作業はなかなかつらみがありますね・・・。