POIで指定範囲内のセル結合を解除する方法

#環境
##java
- java7

## Apache Poi
- [3.14](https://archive.apache.org/dist/poi/release/bin/poi-bin-3.14.zip)

#指定範囲内のセル結合を解除
実行前
![base.PNG](https://qiita-image-store.s3.amazonaws.com/0/148022/d6fbe495-a526-7f1f-47ad-afb0a5285666.png)


Sheetクラスにはそれらしいメソットを見つけられなかったので自分で作ってみました
A2:C6の中にあるセル結合を解除するコード

```java:Sample.java

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;

    public static void main(String[] args) { 
        try(Workbook book = WorkbookFactory.create(Sample.class.getResourceAsStream("sample.xlsx"));
                OutputStream out = new FileOutputStream("sample.xlsx");) {
            XSSFSheet sheet = (XSSFSheet) book.getSheetAt(0);
            
            CellRangeAddress targetRange = CellRangeAddress.valueOf("A2:C6");
            int removeCount = removeMergedRagions(targetRange, sheet);
            System.out.println(removeCount + "個の結合を解除しました");
            
            book.write(out);
        }catch(Exception ex) {
            //なんらかの処理をする
        }

    }
    
    /**
     * 指定した範囲内のセル結合を解除する<br>
     * 一部でも指定範囲に入っている場合は範囲外の結合も解除される
     * @param targetRange 結合を解除する範囲,not {@code null}
     * @param sheet 解除する対象のシート,not {@code null}
     * @return 結合を解除した数
     * @see org.apache.poi.xssf.usermodel.XSSFSheet#removeMergedRegions バージョンがxlsxだけの場合はこちらを使用できる
     */
    private static int removeMergedRegions(CellRangeAddress targetRange ,Sheet sheet) {
        List<CellRangeAddress> mergeList = sheet.getMergedRegions();
        List<Integer> removeIndices = new ArrayList<>();
        
        for(int mergeIndex = 0; mergeIndex < mergeList.size(); mergeIndex++) {
            CellRangeAddress mergedAddress = mergeList.get(mergeIndex);
            if(targetRange.intersects(mergedAddress)) 
                removeIndices.add(mergeIndex);
        }
        //手前から解除するとインデックスが合わなくなるので後ろから消す
        Collections.reverse(removeIndices);
        for(int removeIndex : removeIndices) 
            sheet.removeMergedRegion(removeIndex);
        
        return removeIndices.size();
    }

```

実行ログ
![result.PNG](https://qiita-image-store.s3.amazonaws.com/0/148022/4bcc1b91-1585-b3c0-8060-a7ede492cf9c.png)

実行後
![removeRagions.PNG](https://qiita-image-store.s3.amazonaws.com/0/148022/cdaf5a94-8d83-a6db-f062-41c8cc330cd0.png)

"A2:C6"に一部でも入っていた結合セルは結合が解除されました

メソットの実装：
1.シートから結合情報のリストを取得しmargeListに代入
2.margeListから１個つづ取り出してtargetRangeの範囲内にあるかどうか確認する
3.範囲内にあった場合はそのインデックスをremoveIndicesに入れる
4.前から削除するとインデックスが合わなくなるのを避けるためremoveIndicesの中身を逆順にする
5.最後に後ろから削除する

###XSSFシートのみの場合はこちら

```java:Sample.java

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;

    public static void main(String[] args) { 
        try(Workbook book = WorkbookFactory.create(Sample.class.getResourceAsStream("sample.xlsx"));
                OutputStream out = new FileOutputStream("sample.xlsx");) {
            XSSFSheet sheet = (XSSFSheet) book.getSheetAt(0);
            
            CellRangeAddress targetRange = CellRangeAddress.valueOf("A2:C6");
            int removeCount = removeMargedRagions(targetRange, sheet);
            System.out.println(removeCount + "個の結合を解除しました");
            
            book.write(out);
        }catch(Exception ex) {
            //なんらかの処理をする
        }

    }
    

    /**
     * 指定した範囲内のセル結合を解除する<br>
     * 一部でも指定範囲に入っている場合は範囲外の結合も解除される
     * @param targetRange 結合を解除する範囲,not {@code null}
     * @param xssfSheet 解除する対象のシート,not {@code null}
     * @return 結合を解除した数
     */
    private static int removeMergedRagions(CellRangeAddress targetRange ,XSSFSheet xssfSheet) {
        List<CellRangeAddress> mergeList = xssfSheet.getMergedRegions();
        List<Integer> removeIndices = new ArrayList<>();
        
        for(int mergeIndex = 0; mergeIndex < mergeList.size(); mergeIndex++) {
            CellRangeAddress mergedAddress = mergeList.get(mergeIndex);
            if(targetRange.intersects(mergedAddress)) 
                removeIndices.add(mergeIndex);
        }
        
        xssfSheet.removeMergedRegions(removeIndices);

        return removeIndices.size();
    }

```