3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-12-18

#環境
##java

  • java7

Apache Poi

#指定範囲内のセル結合を解除
実行前
base.PNG

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

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

実行後
removeRagions.PNG

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

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

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

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();
    }

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?