package com.example;

import java.io.FileOutputStream;
import java.nio.file.Path;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class BorderStyleSamples {

    private static final BorderStyle[] ORDERED_BORDER_STYLES = {
            BorderStyle.DASH_DOT,
            BorderStyle.DASH_DOT_DOT,
            BorderStyle.DASHED,
            BorderStyle.DOTTED,
            BorderStyle.DOUBLE,
            BorderStyle.HAIR,
            BorderStyle.MEDIUM,
            BorderStyle.MEDIUM_DASH_DOT,
            BorderStyle.MEDIUM_DASH_DOT_DOT,
            BorderStyle.MEDIUM_DASHED,
            BorderStyle.NONE,
            BorderStyle.SLANTED_DASH_DOT,
            BorderStyle.THICK,
            BorderStyle.THIN
    };

    public static void main(String[] args) throws Exception {
        Path out = Path.of("temp\\BorderStyle_Samples.xlsx");

        try (Workbook wb = new XSSFWorkbook()) {
            Sheet sheet = wb.createSheet("BorderStyle");

            final int blocksPerRow = 4;
            final int sampleWidthCols = 8;
            final int spacerCols = 1;

            int totalCols = blocksPerRow * (sampleWidthCols + spacerCols);
            for (int c = 0; c < totalCols; c++) {
                boolean spacer = ((c + 1) % (sampleWidthCols + spacerCols) == 0);
                sheet.setColumnWidth(c, (spacer ? 2 : 6) * 256);
            }

            Font font = wb.createFont();
            font.setFontName("Calibri");
            font.setFontHeightInPoints((short) 11);
            font.setBold(true);

            int rowIndex = 0;
            int idx = 0;

            while (idx < ORDERED_BORDER_STYLES.length) {
                Row row = sheet.createRow(rowIndex);
                row.setHeightInPoints(28);

                int colBase = 0;

                for (int b = 0; b < blocksPerRow && idx < ORDERED_BORDER_STYLES.length; b++, idx++) {

                    BorderStyle bs = ORDERED_BORDER_STYLES[idx];

                    int startCol = colBase;
                    int endCol = colBase + sampleWidthCols - 1;

                    sheet.addMergedRegion(
                            new CellRangeAddress(rowIndex, rowIndex, startCol, endCol));

                    Cell cell = row.createCell(startCol);
                    cell.setCellValue(bs.name());

                    CellStyle style = wb.createCellStyle();
                    style.setFont(font);

                    // 上罫線でスタイル表示
                    style.setBorderTop(bs);
                    style.setTopBorderColor(IndexedColors.BLACK.getIndex());

                    style.setAlignment(HorizontalAlignment.CENTER);
                    style.setVerticalAlignment(VerticalAlignment.TOP);

                    cell.setCellStyle(style);

                    for (int c = startCol + 1; c <= endCol; c++) {
                        Cell dummy = row.createCell(c);
                        dummy.setCellStyle(style);
                    }

                    // 余白列
                    int spacerCol = endCol + 1;
                    if (spacerCol < totalCols) {
                        row.createCell(spacerCol).setCellValue("");
                    }

                    colBase += (sampleWidthCols + spacerCols);
                }

                rowIndex++;
                if (idx < ORDERED_BORDER_STYLES.length) {
                    rowIndex++; // 行間余白
                }
            }

            try (FileOutputStream fos = new FileOutputStream(out.toFile())) {
                wb.write(fos);
            }
        }

        System.out.println("Created: " + out.toAbsolutePath());
    }
}
