Package com.asakusafw.testtools.templategen

Source Code of com.asakusafw.testtools.templategen.ExcelBookBuilder

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.asakusafw.testtools.templategen;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.MessageFormat;

import org.apache.poi.hssf.usermodel.DVConstraint;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddressList;

import com.asakusafw.testtools.ColumnInfo;
import com.asakusafw.testtools.ColumnMatchingCondition;
import com.asakusafw.testtools.ConditionSheetItem;
import com.asakusafw.testtools.Constants;
import com.asakusafw.testtools.NullValueCondition;
import com.asakusafw.testtools.RowMatchingCondition;
import com.asakusafw.testtools.db.DbUtils;

/**
* Excel Bookを構築する。
*/
public class ExcelBookBuilder {

    private static final String CELL_TRUE = "○";

    private static final String CELL_FALSE = "";

    private static final String CELL_EMPTY = "";

    private final Connection conn;
    private final String tableName;
    private final String databaseName;
    private HSSFWorkbook workbook;
    private ColumnInfo[] columnInfos;
    private HSSFCellStyle commonStyle;
    private HSSFCellStyle titleStyle;
    private HSSFCellStyle centerAlignStyle;
    private HSSFCellStyle fixedValueStyle;
    private HSSFCellStyle centerAlignFixedValueStyle;
    private HSSFCellStyle dateTimeStyle;
    private HSSFCellStyle dateStyle;

    /**
     * インスタンスを生成する。
     * @param conn コネクション
     * @param tableName ソースとなるテーブル名
     * @param databaseName ソースとなるデータベース名
     */
    public ExcelBookBuilder(Connection conn, String tableName, String databaseName) {
        this.conn = conn;
        this.tableName = tableName;
        this.databaseName = databaseName;
    }

    /**
     * Excelブックを生成する。
     * @param outputDirectory 出力先のディレクトリ
     * @throws IOException ブックの生成やファイルの書き出しに失敗した場合
     * @throws SQLException テーブル情報の取得に失敗した場合
     */
    public void build(File outputDirectory) throws IOException, SQLException {
        // カラム情報の取得
        columnInfos = DatabaseSchema.collectColumns(conn, databaseName, tableName);

        // ワークブックを生成
        workbook = new HSSFWorkbook();

        // セルスタイルを作成
        configureColumnStyle();

        // 入力データのシートと出力データのシートを生成
        HSSFSheet inputSheet = createInputDataSheet(Constants.INPUT_DATA_SHEET_NAME);
        int inputSheetIndex = workbook.getSheetIndex(inputSheet);
        HSSFSheet outputSheet = workbook.cloneSheet(inputSheetIndex);
        int outputSheetIndex = workbook.getSheetIndex(outputSheet);
        workbook.setSheetName(outputSheetIndex, Constants.OUTPUT_DATA_SHEET_NAME);

        // テスト条件のシートを生成
        createTestConditionSheet(Constants.TEST_CONDITION_SHEET_NAME);

        // ファイルの生成
        String bookName = tableName + ".xls";
        File outputFile = new File(outputDirectory, bookName);
        OutputStream os = new FileOutputStream(outputFile);
        try {
            workbook.write(os);
        } finally {
            DbUtils.closeQuietly(os);
        }
    }

    private void configureColumnStyle() {
        assert workbook != null;
        HSSFFont font = workbook.createFont();
        font.setFontName("MS ゴシック");

        commonStyle = workbook.createCellStyle();
        commonStyle.setFont(font);
        commonStyle.setBorderTop(CellStyle.BORDER_THIN);
        commonStyle.setBorderBottom(CellStyle.BORDER_THIN);
        commonStyle.setBorderLeft(CellStyle.BORDER_THIN);
        commonStyle.setBorderRight(CellStyle.BORDER_THIN);

        titleStyle = workbook.createCellStyle();
        titleStyle.cloneStyleFrom(commonStyle);
        titleStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        titleStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
        titleStyle.setAlignment(CellStyle.ALIGN_CENTER);

        centerAlignStyle = workbook.createCellStyle();
        centerAlignStyle.cloneStyleFrom(commonStyle);
        centerAlignStyle.setAlignment(CellStyle.ALIGN_CENTER);

        fixedValueStyle = workbook.createCellStyle();
        fixedValueStyle.cloneStyleFrom(commonStyle);
        fixedValueStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        fixedValueStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());

        centerAlignFixedValueStyle = workbook.createCellStyle();
        centerAlignFixedValueStyle.cloneStyleFrom(fixedValueStyle);
        centerAlignFixedValueStyle.setAlignment(CellStyle.ALIGN_CENTER);

        CreationHelper helper = workbook.getCreationHelper();
        DataFormat df = helper.createDataFormat();

        dateTimeStyle = workbook.createCellStyle();
        dateTimeStyle.cloneStyleFrom(commonStyle);
        dateTimeStyle.setDataFormat(df.getFormat("yyyy-mm-dd hh:mm:ss"));

        dateStyle = workbook.createCellStyle();
        dateStyle.cloneStyleFrom(commonStyle);
        dateStyle.setDataFormat(df.getFormat("yyyy-mm-dd"));
    }

    private HSSFCell getCell(HSSFSheet sheet, int rownum, int col) {
        HSSFRow row = sheet.getRow(rownum);
        if (row == null) {
            row = sheet.createRow(rownum);
        }
        HSSFCell cell = row.getCell(col);
        if (cell == null) {
            cell = row.createCell(col);
        }
        cell.setCellStyle(commonStyle);
        return cell;
    }

    private HSSFSheet createTestConditionSheet(String sheetName) {
        // タイトルのセルを作成, 同時にカラム位置の最大値を取得
        int maxColumn = 0;
        HSSFSheet sheet = workbook.createSheet(sheetName);
        for (ConditionSheetItem item : ConditionSheetItem.values()) {
            HSSFCell cell = getCell(sheet, item.getRow(), item.getCol());
            cell.setCellValue(item.getName());
            cell.setCellStyle(titleStyle);
            if (maxColumn < item.getCol()) {
                maxColumn = item.getCol();
            }
        }

        // テーブル名とテーブルのマッチング条件を設定
        HSSFCell tableNameCell = getCell(sheet, ConditionSheetItem.TABLE_NAME
                .getRow(), ConditionSheetItem.TABLE_NAME.getCol() + 1);
        tableNameCell.setCellStyle(fixedValueStyle);
        tableNameCell.setCellValue(tableName);

        HSSFCell rowMatichingConditionCell = getCell(sheet,
                ConditionSheetItem.ROW_MATCHING_CONDITION.getRow(),
                ConditionSheetItem.ROW_MATCHING_CONDITION.getCol() + 1);
        rowMatichingConditionCell.setCellValue(RowMatchingCondition.NONE.getJapaneseName());

        // 各カラムの情報を設定
        int startRow = ConditionSheetItem.NO.getRow();
        int endRow = configureColumns(sheet, startRow);

        // 入力規則を設定
        setExplicitListConstraint(sheet,
                RowMatchingCondition.getJapaneseNames(),
                ConditionSheetItem.ROW_MATCHING_CONDITION.getRow(),
                ConditionSheetItem.ROW_MATCHING_CONDITION.getRow(),
                ConditionSheetItem.ROW_MATCHING_CONDITION.getCol() + 1,
                ConditionSheetItem.ROW_MATCHING_CONDITION.getCol() + 1);

        setExplicitListConstraint(sheet,
                ColumnMatchingCondition.getJapaneseNames(),
                startRow + 1,
                endRow,
                ConditionSheetItem.MATCHING_CONDITION.getCol(),
                ConditionSheetItem.MATCHING_CONDITION.getCol());

        setExplicitListConstraint(sheet,
                NullValueCondition.getJapaneseNames(),
                startRow + 1,
                endRow,
                ConditionSheetItem.NULL_VALUE_CONDITION.getCol(),
                ConditionSheetItem.NULL_VALUE_CONDITION.getCol());


        // カラム幅の調整
        for (int i = 0; i <= maxColumn + 1; i++) {
            sheet.autoSizeColumn(i);
        }
        return sheet;
    }

    private int configureColumns(HSSFSheet sheet, int startRow) {
        assert columnInfos != null;
        int row = startRow;
        int no = 0;
        for (ColumnInfo info : columnInfos) {
            row++;
            no++;

            HSSFCell noCell = getCell(sheet, row, ConditionSheetItem.NO.getCol());
            noCell.setCellStyle(centerAlignFixedValueStyle);
            noCell.setCellValue(no);

            HSSFCell columnNameCell = getCell(sheet, row, ConditionSheetItem.COLUMN_NAME.getCol());
            columnNameCell.setCellStyle(fixedValueStyle);
            columnNameCell.setCellValue(info.getColumnName());

            HSSFCell columnCommentCell = getCell(sheet, row, ConditionSheetItem.COLUMN_COMMENT.getCol());
            columnCommentCell.setCellStyle(fixedValueStyle);
            columnCommentCell.setCellValue(info.getColumnComment());

            HSSFCell dataTypeCell = getCell(sheet, row, ConditionSheetItem.DATA_TYPE.getCol());
            dataTypeCell.setCellStyle(centerAlignFixedValueStyle);
            dataTypeCell.setCellValue(info.getDataType().getDataTypeString());

            HSSFCell widthCell = getCell(sheet, row, ConditionSheetItem.WIDTH.getCol());
            widthCell.setCellStyle(centerAlignFixedValueStyle);
            switch (info.getDataType()) {
            case CHAR:
            case VARCHAR:
                widthCell.setCellValue(info.getCharacterMaximumLength());
                break;
            case DECIMAL:
                widthCell.setCellValue(info.getNumericPrecision());
                break;
            case DATE:
            case DATETIME:
            case INT:
            case LONG:
            case SMALL_INT:
            case TIMESTAMP:
            case TINY_INT:
                widthCell.setCellValue(CELL_EMPTY);
                break;
            default:
                throw new RuntimeException(MessageFormat.format(
                        "Unkonwn data type: {0}",
                        info.getDataType().name()));
            }

            HSSFCell scaleCell = getCell(sheet, row, ConditionSheetItem.SCALE.getCol());
            scaleCell.setCellStyle(centerAlignFixedValueStyle);
            switch (info.getDataType()) {
            case DECIMAL:
                scaleCell.setCellValue(info.getNumericScale());
                break;
            case CHAR:
            case DATE:
            case DATETIME:
            case INT:
            case LONG:
            case SMALL_INT:
            case TIMESTAMP:
            case TINY_INT:
            case VARCHAR:
                scaleCell.setCellValue(CELL_EMPTY);
                break;
            default:
                throw new RuntimeException(MessageFormat.format(
                        "Unkonwn data type: {0}",
                        info.getDataType().name()));
            }

            HSSFCell nullableCell = getCell(sheet, row, ConditionSheetItem.NULLABLE.getCol());
            nullableCell.setCellStyle(centerAlignFixedValueStyle);
            if (info.isNullable()) {
                nullableCell.setCellValue(CELL_TRUE);
            } else {
                nullableCell.setCellValue(CELL_FALSE);
            }

            HSSFCell pkCell = getCell(sheet, row, ConditionSheetItem.KEY_FLAG.getCol());
            pkCell.setCellStyle(centerAlignStyle);
            if (info.isKey()) {
                pkCell.setCellValue(CELL_TRUE);
            } else {
                pkCell.setCellValue(CELL_FALSE);
            }

            HSSFCell machingCondtionCell = getCell(sheet, row, ConditionSheetItem.MATCHING_CONDITION.getCol());
            machingCondtionCell.setCellStyle(centerAlignStyle);
            machingCondtionCell.setCellValue(ColumnMatchingCondition.NONE.getJapaneseName());

            HSSFCell nullValueConditionCell = getCell(sheet, row, ConditionSheetItem.NULL_VALUE_CONDITION.getCol());
            nullValueConditionCell.setCellStyle(centerAlignStyle);
            nullValueConditionCell.setCellValue(NullValueCondition.NORMAL.getJapaneseName());

        }
        int endRow = row;
        return endRow;
    }

    private void setExplicitListConstraint(
            HSSFSheet sheet,
            String[] list,
            int firstRow,
            int lastRow,
            int firstCol,
            int lastCol) {
        //データの入力規則を設定するセルを設定する
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        DVConstraint constraint = DVConstraint.createExplicitListConstraint(list);
        HSSFDataValidation validation = new HSSFDataValidation(addressList, constraint);
        validation.setEmptyCellAllowed(true);
        validation.setSuppressDropDownArrow(false);
        sheet.addValidationData(validation);
    }

    /**
     * 入力データのシートを生成する。
     * @param sheetName 入力データのシート名
     * @return 生成したシート
     * @throws SQLException データベースから入力データを取得するのに失敗した場合
     */
    private HSSFSheet createInputDataSheet(String sheetName) throws SQLException {
        HSSFSheet sheet = workbook.createSheet(sheetName);

        // カラム名を設定
        HSSFRow row = sheet.createRow(0);
        for (int i = 0; i < columnInfos.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(columnInfos[i].getColumnName());
            cell.setCellStyle(titleStyle);
        }

        // DBのデータを設定
        PreparedStatement ps = null;
        ResultSet rs = null;

        String sql =
            "SELECT * FROM "
            + databaseName + "." + tableName
            + " limit 0, " + Constants.MAX_ROWS;
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                row = sheet.createRow(row.getRowNum() + 1);
                for (int i = 0; i < columnInfos.length; i++) {
                    ColumnInfo info = columnInfos[i];
                    HSSFCell cell = row.createCell(i);
                    cell.setCellStyle(commonStyle);
                    switch (info.getDataType()) {
                    case CHAR:
                    case VARCHAR:
                        String str = rs.getString(info.getColumnName());
                        if (!rs.wasNull()) {
                            cell.setCellValue(str);
                        }
                        break;
                    case DATE:
                        Date date = rs.getDate(info.getColumnName());
                        if (!rs.wasNull()) {
                            cell.setCellValue(new java.util.Date(date.getTime()));
                            cell.setCellStyle(dateStyle);
                        }
                        break;
                    case DATETIME:
                    case TIMESTAMP:
                        Timestamp ts = rs.getTimestamp(info.getColumnName());
                        if (!rs.wasNull()) {
                            cell.setCellValue(new java.util.Date(ts.getTime()));
                            cell.setCellStyle(dateTimeStyle);
                        }
                        break;
                    case DECIMAL:
                        BigDecimal decimal = rs.getBigDecimal(info.getColumnName());
                        if (!rs.wasNull()) {
                            cell.setCellValue(decimal.toPlainString());
                        }
                        break;
                    case TINY_INT:
                    case SMALL_INT:
                    case INT:
                    case LONG:
                        long value = rs.getLong(info.getColumnName());
                        if (!rs.wasNull()) {
                            cell.setCellValue(Long.toString(value));
                        }
                        break;
                    default:
                        assert false;
                        break;
                    }
                }
            }
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        // カラム幅の調整
        for (int i = 0; i < columnInfos.length; i++) {
            sheet.autoSizeColumn(i);
        }
        return sheet;
    }
}
TOP

Related Classes of com.asakusafw.testtools.templategen.ExcelBookBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.