2013年10月20日日曜日

groovyとApache POIを使用してExcelにデータベース型、ペーパー型、角丸四角を描画する

groovyとApache POIを使用してExcelにデータベース型、ペーパー型、角丸四角を描画するには、以下のコードを実行します。
// 3.9だとXSSFRichTextStringにフォントの設定が効かない
//@Grab(group='org.apache.poi', module='poi-ooxml', version='3.9')
@Grab(group='org.apache.poi', module='poi-ooxml', version='3.10-beta2')
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;

workbook = new XSSFWorkbook()
sheet = workbook.createSheet("sheet1")

XSSFDrawing patriarch = sheet.createDrawingPatriarch()

// -----------------------------------------------
// データベース形を描画
ca1 = new XSSFClientAnchor( 0, 0, 0, 0,  
  /* top-left */ (short)1, 1,  /* right-bottom */ (short)3, 5 )
ca1.setAnchorType(ca1.MOVE_AND_RESIZE)
db1 = patriarch.createSimpleShape(ca1)
db1.setShapeType(ShapeTypes.CAN)
font1 = workbook.createFont()
font1.setColor(XSSFFont.DEFAULT_FONT_COLOR)
font1.setFontName("MS Pゴシック")
font1.setFontHeightInPoints((short)12)

rts = new XSSFRichTextString("Database1")
rts.applyFont(font1)
db1.setText(rts)
// 線の色と太さ
db1.setLineStyleColor(0x00, 0x00, 0x00)
db1.setLineWidth(1)
// 塗りつぶし無しに設定
db1.setNoFill(true)

// -----------------------------------------------
// 文書形を描画
ca2 = new XSSFClientAnchor( 0, 0, 0, 0,  
  /* top-left */ (short)1, 6,  /* right-bottom */ (short)3, 8 )
ca2.setAnchorType(ca1.MOVE_AND_RESIZE)
doc1 = patriarch.createSimpleShape(ca2)
doc1.setShapeType(ShapeTypes.FOLDED_CORNER  )

rts2 = new XSSFRichTextString("Document1")
rts2.applyFont(font1)
doc1.setText(rts2)
// 線の色と太さ
doc1.setLineStyleColor(0x00, 0x00, 0x00)
doc1.setLineWidth(1)
// 塗りつぶし無しに設定
doc1.setNoFill(true)

// -----------------------------------------------
// 角丸四角を描画
ca3 = new XSSFClientAnchor( 0, 0, 0, 0,  
  /* top-left */ (short)1, 9,  /* right-bottom */ (short)3, 11 )
ca3.setAnchorType(ca1.MOVE_AND_RESIZE)
rr1 = patriarch.createSimpleShape(ca3)
rr1.setShapeType(ShapeTypes.ROUND_RECT  )

rts3 = new XSSFRichTextString("角丸")
rts3.applyFont(font1)
rr1.setText(rts3)
// 線の色と太さ
rr1.setLineStyleColor(0x00, 0x00, 0x00)
rr1.setLineWidth(1)
// 塗りつぶし無しに設定
rr1.setNoFill(true)

workbook.write(new FileOutputStream("test.xlsx"))
出力画面

動作環境
groovy 2.1.7, JDK7 update40

2013年10月19日土曜日

groovyとApache MetaModelでクエリーのソートを使用する

groovyとApache MetaModelでクエリーのソートを使用するには、以下のコードのようにorderByを使用します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import groovy.sql.Sql

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

dc1 = DataContextFactory.createJdbcDataContext(sql.getConnection())

// スコアテーブルの取得とカラムの取得
tableScores = dc1.getDefaultSchema().getTableByName("scores")
colScoresTestId = tableScores.getColumnByName("test_id") // テストID
colScoresStudentId = tableScores.getColumnByName("student_id") // 生徒ID
colScoresScore = tableScores.getColumnByName("score")  // 点数

// 数学のテストのスコアを降順にソートする
query = dc1.query().from(tableScores)
  .select(colScoresStudentId, colScoresScore)
  .where(colScoresTestId).eq("mathematics")
  .orderBy(colScoresScore).desc()
  .toQuery()

// Queryの表示
println query.toString()
// Queryの実行
ds = dc1.executeQuery(query)
for(row in ds){
  // student_id, 点数を表示
  println row.getValue(0) + ":" + row.getValue(1)
}

2013年10月18日金曜日

groovyとApache MetaModelでカラムの型変換を行う

groovyとApache MetaModelでカラムの型変換を行うには、以下のようにConverters.addTypeConverterメソッドを使用します。
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import org.eobjects.metamodel.convert.*

dc = DataContextFactory.createExcelDataContext(new File("products.xlsx"))
// テーブル(=シート)を指定
table = dc.getDefaultSchema().getTableByName("products")
colPrice = table.getColumnByName("price")
// 文字列から数値へのConverterを設定
Converters.addTypeConverter(dc, colPrice, new StringToIntegerConverter())

// 値段が2000円以上の製品を抽出
query = dc.query().from(table)
  .select("product_name", "price")
  .where(colPrice).gt(2000)
    .or(colPrice).eq(2000)
  .toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // 製品名と価格を表示
  println row.getValue(0) + ":" + row.getValue(1)
}


動作環境
groovy 2.1.7, JDK7 update40

2013年10月17日木曜日

groovyとApache MetaModelでテーブル・カラムを一覧表示する

groovyとApache MetaModelでテーブル・カラムを一覧表示するには、以下のコードを実行します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import groovy.sql.Sql

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

dc = DataContextFactory.createJdbcDataContext(sql.getConnection())
// テーブルの一覧を表示する
for(tab in dc.getDefaultSchema().getTables())
{
  println "table:" + tab.getName()
  // テーブルのカラムを一覧表示する
  for(col in tab.getColumns())
  {
    println "  col:" + col.getName() + ":" + 
      col.getType() + "," + col.getNativeType() + 
      ":" + (col.isNullable()?"NULLABLE":"NOT NULL")
  }
}

動作環境
groovy 2.1.7, JDK7 update40

2013年10月16日水曜日

groovyとApache MetaModelでRDBとExcelのデータをJOINしたクエリーを実行する

異なるデータソース(RDBとExcelなど)のテーブルをJOINしたクエリーを実行するには、以下のようにDataContextFactory.createCompositeDataContextメソッドを使用して、CompositeDataContextを作成します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import groovy.sql.Sql

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

// RDB(JDBC)
dc1 = DataContextFactory.createJdbcDataContext(sql.getConnection())
// Excel DataContext
dc2 = DataContextFactory.createExcelDataContext(new File("students.xlsx"))

// Composite DataContextを作成
cdc = DataContextFactory.createCompositeDataContext(dc1, dc2)

// スコアテーブルの取得とカラムの取得
tableScores = cdc.getDefaultSchema().getTableByName("scores")
colScoresTestId = tableScores.getColumnByName("test_id") // テストID
colScoresStudentId = tableScores.getColumnByName("student_id") // 生徒ID
colScoresScore = tableScores.getColumnByName("score")  // 点数

// 生徒マスタの取得とカラムの取得
tableStudents = dc2.getDefaultSchema().getTableByName("students")
colStudentsStudentId = tableStudents.getColumnByName("student_id") // 生徒ID
colStudentsName = tableStudents.getColumnByName("name")  // 生徒名

// 2つのテーブルをjoin。90点以上取った生徒の名前とスコア、テストIDを表示
query = cdc.query().from(tableScores)
  .leftJoin(tableStudents).on(colScoresStudentId, colStudentsStudentId)
  .select(colScoresTestId, colStudentsName, colScoresScore)
  .where(colScoresScore).gt(90)
    .or(colScoresScore).eq(90)
  .toQuery()

// Queryの表示
println query.toString()
// Queryの実行
ds = cdc.executeQuery(query)
for(row in ds){
  // test_id, 名前, 点数を表示
  println row.getValue(0) + ":" + row.getValue(1) + ":" + row.getValue(2)
}


動作環境
groovy 2.1.7, JDK7 update40

2013年10月15日火曜日

groovyとApache POIを使用してExcelにテキストボックスを描画する

groovyとApache POIを使用してExcelにテキストボックスを描画するには、以下のコードを実行します。
@Grab(group='org.apache.poi', module='poi', version='3.9')
import org.apache.poi.hssf.usermodel.*;

workbook = new HSSFWorkbook()
sheet = workbook.createSheet("sheet1")

HSSFPatriarch patriarch = sheet.createDrawingPatriarch()

// テキストボックスを描画
ca1 = new HSSFClientAnchor( 0, 0, 0, 0,  
  /* top-left */ (short)1, 2,  /* right-bottom */ (short)3, 4 )
ca1.setAnchorType(ca1.MOVE_AND_RESIZE)
textbox1 = patriarch.createTextbox(ca1)
textbox1.setString(new HSSFRichTextString("サンプル"))

// 中央寄せした色つきテキストボックスを描画
ca2 = new HSSFClientAnchor( 0, 0, 0, 0, 
  /* top-left */ (short)1, 5,  /* right-bottom */ (short)3, 7 )
ca2.setAnchorType(ca2.MOVE_AND_RESIZE)
textbox2 = patriarch.createTextbox(ca2)
textbox2.setString(new HSSFRichTextString("中央寄せサンプル"))
// 水平中央寄せ
textbox2.setHorizontalAlignment(HSSFTextbox.HORIZONTAL_ALIGNMENT_CENTERED)
// 垂直中央寄せ
textbox2.setVerticalAlignment(HSSFTextbox.VERTICAL_ALIGNMENT_CENTER)
// 線の色を設定
textbox2.setLineStyleColor(0x77, 0x99, 0xdd)
// 塗りつぶし色を設定
textbox2.setFillColor(0xcc, 0xdd, 0xff)

workbook.write(new FileOutputStream("test.xls"))
出力ファイル

動作環境
groovy 2.1.7, JDK7 update40

2013年10月14日月曜日

groovyとjava-diff-utilsで2つのファイルの違いを表示する

groovyとjava-diff-utilsで2つのファイルの違いを表示するには、以下のコードを実行します。
@Grab(group='com.googlecode.java-diff-utils', module='diffutils', version='1.3.0')
import difflib.*

// ファイル1の各行を読み込み
def lines1 = []
new File("test1.txt").withReader { reader ->
  while((line = reader.readLine()) != null){ lines1 << line }
}

// ファイル2の各行を読み込み
def lines2 = []
new File("test1b.txt").withReader { reader ->
  while((line = reader.readLine()) != null){ lines2 << line }
}

// Diff実行
drg = new DiffRowGenerator.Builder().build()
rows = drg.generateDiffRows(lines1, lines2)
rows.eachWithIndex { row, idx ->
  switch(row.getTag()){
  case DiffRow.Tag.INSERT:
    println "INSERTED:${idx}:${row.getNewLine()}"
    break
  case DiffRow.Tag.DELETE:
    println "DELETED:${idx}:${row.getOldLine()}"
    break
  case DiffRow.Tag.CHANGE:
    println "BEFORE:${idx}:${row.getOldLine()}"
    println "AFTER:${idx}:${row.getNewLine()}"
    break
  default:
    println "${idx}:${row.getOldLine()}"
  }
}


動作環境
groovy 2.1.7, JDK7 update40

groovyとApache MetaModelで集約関数を使用する

groovyとApache MetaModelで集約関数を使用するには、以下のコードのようにFunctionTypeとカラムを使用します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import org.eobjects.metamodel.query.*
import groovy.sql.Sql

/*
以下のようなテスト結果テーブルscoresからテスト(test_id)毎の点数(score)の
平均・件数・最大・最小・合計を求める。

CREATE TABLE scores
(
  test_id character varying(100) NOT NULL,
  student_id character varying(6) NOT NULL,
  score integer,
  CONSTRAINT pk_scores PRIMARY KEY (test_id , student_id )
)
*/

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

dc = DataContextFactory.createJdbcDataContext(sql.getConnection())
// テーブル(=シート)を指定
table = dc.getDefaultSchema().getTableByName("scores")
colTestId = table.getColumnByName("test_id")
colScore = table.getColumnByName("score")

// テスト毎に集計結果を取得
query = dc.query().from(table)
  .select(colTestId)
    .and(FunctionType.AVG, colScore)
    .and(FunctionType.COUNT, colScore)
    .and(FunctionType.MAX, colScore)
    .and(FunctionType.MIN, colScore)
    .and(FunctionType.SUM, colScore)
  .groupBy(colTestId)
  .toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // 集約結果を表示
  println row.getValue(0) + 
    ":AVG=" + row.getValue(1) + 
    ":COUNT=" + row.getValue(2) + 
    ":MAX=" + row.getValue(3) + 
    ":MIN=" + row.getValue(4) + 
    ":SUM=" + row.getValue(5)
}


動作環境
groovy 2.1.7, JDK7 update40

2013年10月13日日曜日

groovyとApache MetaModelでPOJOのリストに対してクエリーを実行する

groovyとApache MetaModelでPOJOのリストに対してクエリーを実行するには、以下のようにObjectTableDataProviderクラスとPojoDataContextクラスを使用します。
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import org.eobjects.metamodel.pojo.*

class ComputerLang
{
  // 言語ID
  int langID
  // 言語名称
  String name
}

languages = [
  new ComputerLang(langID:1, name:"C"),
  new ComputerLang(langID:2, name:"java"),
  new ComputerLang(langID:3, name:"groovy")
]

providerComputerLang = new ObjectTableDataProvider<ComputerLang>(
  "languages", ComputerLang.class, languages
)
dc = new PojoDataContext([providerComputerLang])
table = dc.getDefaultSchema().getTable(0)
// 言語IDが3の言語を抽出
query = dc.query().from(table)
  .select("langID", "name")
  .where(table.getColumnByName("langID")).equals(3).toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // LangIDと言語を表示
  println row.getValue(0) + ":" + row.getValue(1)
}


動作環境
groovy 2.1.7, JDK7 update40

2013年10月12日土曜日

groovyとApache MetaModelでXMLファイルに対してクエリーを実行する

groovyとApache MetaModelでXMLファイルに対してクエリーを実行するには、以下のようなコードを実行します。
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import org.eobjects.metamodel.xml.*

// XMLファイルに対するテーブル構造を定義
XmlSaxTableDef prjTableDef = new XmlSaxTableDef(
  "/projects/project",
  [
    "/projects/project@name",
    "/projects/project/owner"
  ] as String[]
)

dc = new XmlSaxDataContext(new File("projects.xml"), prjTableDef)
// テーブルを指定
table = dc.getDefaultSchema().getTableByName("/project")

// 所有者がuser2のプロジェクトを抽出
query = dc.query().from(table)
  .select("row_id", "@name", "/owner")
  .where(table.getColumnByName("/owner")).eq("user2").toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // row_idとプロジェクト名、所有者を表示
  println row.getValue(0) + ":" + row.getValue(1) + ":" + row.getValue(2)
}

サンプルXMLファイル
<?xml version="1.0" encoding="UTF-8"?>
<projects>
  <project name="テストプロジェクト1">
    <owner>user1</owner>
  </project>
  <project name="テストプロジェクト2">
    <owner>user2</owner>
  </project>
  <project name="テストプロジェクト3">
    <owner>user3</owner>
  </project>
</projects>

動作環境
groovy 2.1.7, JDK7 update40

2013年10月11日金曜日

groovyとApache MetaModelでMongoDBのコレクションに対してクエリーを実行する

groovyとApache MetaModelでMongoDBのコレクションに対してクエリーを実行するには、以下のようなコードを実行します。
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*

dc = DataContextFactory.createMongoDbDataContext("mongodb-srv", 27017, "local", "user", [] as char[])
// テーブル(=コレクション)を指定
table = dc.getDefaultSchema().getTableByName("sales")

// SKUが003の売上データを抽出
query = dc.query().from(table)
  .select("total_sales")
  .where(table.getColumnByName("sku")).eq("003").toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // 売上データを表示
  println row.getValue(0)
}


動作環境
groovy 2.1.7, JDK7 update40

2013年10月10日木曜日

groovyとApache MetaModelでRDBのテーブルに対してクエリーを実行する

groovyとApache MetaModelでRDBのテーブルに対してクエリーを実行するには、以下のようなコードを実行します。
@GrabConfig(systemClassLoader=true)
@Grab(group='postgresql', module='postgresql', version='9.1-901.jdbc4')
@Grab(group='org.eobjects.metamodel', module='MetaModel-full', version='3.4.5')
import org.eobjects.metamodel.*
import groovy.sql.Sql

def sql = Sql.newInstance(
  "jdbc:postgresql://localhost:5432/userdb",
  "postgres",
  "postgres",
  "org.postgresql.Driver")

dc = DataContextFactory.createJdbcDataContext(sql.getConnection())
// テーブル(=シート)を指定
table = dc.getDefaultSchema().getTableByName("customer")

// 顧客IDが1011のデータを抽出
query = dc.query().from(table)
  .select("customer_id", "customer_name")
  .where(table.getColumnByName("customer_id")).eq(1011).toQuery()
// Queryの表示
println query.toString()
// Queryの実行
ds = dc.executeQuery(query)
for(row in ds){
  // 顧客IDと顧客名を表示
  println row.getValue(0) + ":" + row.getValue(1)
}


動作環境
groovy 2.1.7, JDK7 update40