Skip to content

Instantly share code, notes, and snippets.

@gitbricho
Last active March 6, 2016 05:49
Show Gist options
  • Save gitbricho/2a10f7603d9de8ac869b to your computer and use it in GitHub Desktop.
Save gitbricho/2a10f7603d9de8ac869b to your computer and use it in GitHub Desktop.
osx pdf create
import Cocoa
//MARK: 定数定義
let L行高 = CGFloat(10.2)
let L行数 = 80
let Lマージン上 = CGFloat(10.0) //mm 単位
let Lマージン左 = CGFloat(10.0)
let Lマージン右 = CGFloat(10.0)
let Lマージン下 = CGFloat(10.0)
// 70DPI -> 70dot/25.4mm = 2.756
let Lピクセル換算 = CGFloat(2.756)
let LA4縦 = CGSize(width: 579, height: 819)
let LA4横 = CGSize(width: 819, height: 579)
let Lフォントサイズ = CGFloat(10)
// PDFテーブルセル
struct PDFテーブルセル {
var zテキスト: String = ""
var zセル幅: CGFloat
var zフォント: NSFont = NSFont(name: "Helvetica",
size: Lフォントサイズ)!
var z文字色: NSColor = NSColor.blackColor()
var z水平配置: NSTextAlignment = NSLeftTextAlignment
var z枠線: CGFloat = 0
var zイメージ: Bool = false
init(テキスト:String, セル幅:CGFloat) {
zテキスト = テキスト
zセル幅 = セル幅
}
init(テキスト:String, セル幅:CGFloat,
水平配置:NSTextAlignment, 枠線:CGFloat) {
zテキスト = テキスト
zセル幅 = セル幅
z水平配置 = 水平配置
z枠線 = 枠線
}
init(テキスト:String, セル幅:CGFloat, フォント:NSFont,
文字色:NSColor, 水平配置:NSTextAlignment, 枠線:CGFloat) {
zテキスト = テキスト
zセル幅 = セル幅
zフォント = フォント
z文字色 = 文字色
z水平配置 = 水平配置
z枠線 = 枠線
}
init(テキスト:String, セル幅:CGFloat, イメージ: Bool) {
zテキスト = テキスト
zセル幅 = セル幅
zイメージ = イメージ
}
}
// PDFテーブル行
// テーブル形式で出力する PDFぺージの行を定義する。
// テーブルのヘッダ行、データ行、フッタ行を定義。
struct PDFテーブル行 {
var z列リスト : [PDFテーブルセル]
// TODO: さらに行固有情報を追加
init(列リスト: [PDFテーブルセル]) {
z列リスト = 列リスト
}
}
// PDFテーブル
// ひとつのぺージのテーブル内の行のリストを保持する。
struct PDFテーブル {
var z行リスト:[PDFテーブル行]
init(行リスト:[PDFテーブル行]) {
z行リスト = 行リスト
}
}
import Cocoa
import Quartz
class PdfTablePage: PdfWriter {
//MARK:プロパティ
var zテーブル: PDFテーブル
//MARK:イニシャライザ
init(ページサイズ:CGSize, 行数:Int,
マージン上:CGFloat, マージン左:CGFloat,
マージン右:CGFloat, マージン下:CGFloat,
ヘッダ: String, フッタ: String, ページ番号:Int,
テーブル:PDFテーブル) {
zテーブル = テーブル
super.init(ページサイズ: ページサイズ, 行数: 行数,
マージン上: マージン上, マージン左: マージン左,
マージン右: マージン右, マージン下: マージン下,
ヘッダ: ヘッダ, フッタ: フッタ, ページ番号: ページ番号)
}
//MARK:メソッド
//テーブルの行を描画
func fテーブル行描画(行: PDFテーブル行, 行番号: Int) {
var x:CGFloat = zマージン左
let y:CGFloat = zマージン上 + z行高 * CGFloat(行番号)
var vセル番号 = 0
for セル in 行.z列リスト {
if (!セル.zイメージ) {
self.fテキスト描画(x, y: y,
w: セル.zセル幅, h: z行高,
テキスト: セル.zテキスト,
文字色: セル.z文字色,
フォント: セル.zフォント,
水平配置: セル.z水平配置)
} else {
let image: NSImage = NSImage(named: セル.zテキスト)!
image.drawInRect(NSMakeRect(
x, zページサイズ.height - y, セル.zセル幅, z行高))
}
if セル.z枠線 > 0 {
f枠描画(x, y: y, w: セル.zセル幅, h: z行高, 線幅: セル.z枠線)
}
x += セル.zセル幅
vセル番号++
}
}
func f枠描画(x:CGFloat, y:CGFloat, w:CGFloat, h:CGFloat,
線幅:CGFloat = 1.0) {
let yy = zページサイズ.height - y
let path = NSBezierPath(rect: NSMakeRect(x, yy, w, h))
NSColor.lightGrayColor().set()
path.lineWidth = 線幅
path.stroke()
}
override func drawWithBox(box: PDFDisplayBox) {
super.drawWithBox(box)
var v行番号 = 0
//ページヘッダ出力:あり
let lヘッダ色 = NSColor.blueColor()
let lヘッダフォント = NSFont(name: "Helvetica Bold", size: 10.0)!
fテキスト描画(
zマージン左, y: zマージン上,
w: 300.0, h: z行高,
テキスト: "PDFテーブルサンプル",
文字色: lヘッダ色, フォント: lヘッダフォント,
水平配置: NSLeftTextAlignment)
v行番号++
//テーブル行出力
for 行 in zテーブル.z行リスト {
fテーブル行描画(行, 行番号: v行番号++)
}
//ぺージフッタ出力:なし
//ページ番号
if zページ番号 > 0 {
let lフォント:NSFont = NSFont(name: "Helvetica", size: 8.0)!
fページ番号描画(zページ番号, フォント: lフォント)
}
}
}
import Cocoa
import Quartz
class PdfWriter : PDFPage {
//MARK:プロパティ
var z行数 = L行数
var zマージン上 = Lマージン上 * Lピクセル換算
var zマージン左 = Lマージン左 * Lピクセル換算
var zマージン右 = Lマージン右 * Lピクセル換算
var zマージン下 = Lマージン下 * Lピクセル換算
var zページサイズ = LA4縦
var zフォント = NSFont(name: "Helvetica", size: Lフォントサイズ)!
var z背景: NSImage?
var zヘッダ: String = ""
var zフッタ: String = ""
var zページ番号: Int = 0
var z行高: CGFloat {
return (zページサイズ.height / CGFloat(z行数))
}
//MARK:イニシャライザ
init(ページサイズ:CGSize, 行数:Int,
マージン上:CGFloat, マージン左:CGFloat,
マージン右:CGFloat, マージン下:CGFloat,
ヘッダ: String, フッタ: String, ページ番号:Int) {
super.init()
zページサイズ = ページサイズ
z行数 = 行数
zマージン上 = マージン上 * Lピクセル換算
zマージン左 = マージン左 * Lピクセル換算
zマージン右 = マージン右 * Lピクセル換算
zマージン下 = マージン下 * Lピクセル換算
zヘッダ = ヘッダ
zフッタ = フッタ
zページ番号 = ページ番号
}
//MARK:メソッド
func fページ番号描画(ページ番号:Int, フォント: NSFont) {
let l番号色 = NSColor.blackColor()
fテキスト描画(
zマージン左, y: zページサイズ.height - (zマージン下 - z行高),
w: zページサイズ.width - zマージン左 - zマージン右, h: z行高,
テキスト: "\(ページ番号)",
文字色: l番号色,
フォント: フォント,
水平配置: NSCenterTextAlignment)
}
func fテキスト描画(x:CGFloat, y:CGFloat, w:CGFloat, h:CGFloat,
テキスト:String, 文字色:NSColor, フォント:NSFont,
水平配置:NSTextAlignment, 方向: String = "") {
let lスタイル = NSMutableParagraphStyle()
lスタイル.alignment = 水平配置
let l描画属性 = [
NSFontAttributeName: フォント ?? NSFont.labelFontOfSize(12),
NSParagraphStyleAttributeName: lスタイル,
NSForegroundColorAttributeName: 文字色
]
if 方向 != "縦" {
テキスト.drawInRect(NSMakeRect(x, zページサイズ.height - y + 1, w, h),
withAttributes: l描画属性)
} else {
var 縦テキスト:String = ""
テキスト.characters.forEach { (x) -> () in
縦テキスト += String(x) + "\n"
}
縦テキスト.drawInRect(
NSMakeRect(x, zページサイズ.height - y + 1, w, h),
withAttributes: l描画属性)
}
}
override func boundsForBox(box: PDFDisplayBox) -> NSRect
{
return NSMakeRect(0, 0, zページサイズ.width, zページサイズ.height)
}
override func drawWithBox(box: PDFDisplayBox) {
}
}
import Cocoa
import Quartz
class ViewController: NSViewController {
struct S成績 {
var 名前: String = ""
var 性別: Int = 0
var 1学期試験結果: (英語: Int, 数学: Int, 国語: Int, 合計: Int)
var 2学期試験結果: (英語: Int, 数学: Int, 国語: Int, 合計: Int)
init(名前: String,
性別: Int,
1学期試験結果: (英語: Int, 数学: Int, 国語: Int, 合計: Int),
2学期試験結果: (英語: Int, 数学: Int, 国語: Int, 合計: Int)) {
self.名前 = 名前
self.性別 = 性別
self.1学期試験結果 = 1学期試験結果
self.2学期試験結果 = 2学期試験結果
}
}
//MARK:プロパティ
@IBOutlet weak var pdfCreBtn2: NSButton!
var zテーブルヘッダ: [PDFテーブル行] = []
var zテーブルフッタ: [PDFテーブル行] = []
var zテーブルデータ: [PDFテーブル行] = []
override func viewDidLoad() {
super.viewDidLoad()
データ設定()
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
func 点数生成() -> (Int, Int, Int, Int) {
let l最低点 = Int(rand() % 70 + 1)
let l点数1 = Int(rand() % (100-l最低点) + l最低点 + 1)
let l点数2 = Int(rand() % (100-l最低点) + l最低点 + 1)
let l点数3 = Int(rand() % (100-l最低点) + l最低点 + 1)
let l合計点数 = l点数1 + l点数2 + l点数3
return (l点数1, l点数2, l点数3, l合計点数)
}
func 合計計算(点数:(Int, Int, Int, Int),
試験結果:(Int, Int, Int, Int)) -> (Int, Int, Int, Int) {
return (点数.0+試験結果.0,
点数.1+試験結果.1,
点数.2+試験結果.2,
点数.3+試験結果.3
)
}
// PDFテーブルに出力するサンプルデータを準備する。
func データ設定() {
var vサンプルデータ: [S成績] = []
// サンプルデータ配列にデータ100件を追加。実際にはDBやファイルから読み込む。
for var i=0; i < 100; i++ {
vサンプルデータ.append(
S成績(名前: "名前\(10000 + i)",
性別: Int(rand() % 2),
1学期試験結果: 点数生成(),
2学期試験結果: 点数生成()
)
)
}
let lイメージ名:[String] = ["male1", "female"]
//枠線の幅
let lヘッダ線幅:CGFloat = 1.0
let lデータ線幅:CGFloat = 0.5
//テーブルセルの幅
let l点数セル幅: CGFloat = 45
let l名前セル幅: CGFloat = 100
let l性別セル幅: CGFloat = 12
// テーブルヘッダは2行
zテーブルヘッダ.append(
PDFテーブル行(列リスト: [
PDFテーブルセル(テキスト: "", セル幅: l性別セル幅 + l名前セル幅),
PDFテーブルセル(テキスト: "1学期", セル幅: l点数セル幅 * 4,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "2学期", セル幅: l点数セル幅 * 4,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅)
])
)
zテーブルヘッダ.append(
PDFテーブル行(列リスト: [
PDFテーブルセル(テキスト: "", セル幅: l性別セル幅),
PDFテーブルセル(テキスト: "名前", セル幅: l名前セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "英語", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "数学", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "国語", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "合計", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "英語", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "数学", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "国語", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "合計", セル幅: l点数セル幅,
水平配置: NSCenterTextAlignment, 枠線: lヘッダ線幅)
])
)
var v1学期合計:(Int, Int, Int, Int) = (0,0,0,0)
var v2学期合計:(Int, Int, Int, Int) = (0,0,0,0)
// サンプルデータからテーブルのデータ行を作成。
for 試験結果 in vサンプルデータ {
zテーブルデータ.append(
PDFテーブル行(列リスト: [
PDFテーブルセル(テキスト: lイメージ名[試験結果.性別],
セル幅: l性別セル幅, イメージ: true),
PDFテーブルセル(テキスト: 試験結果.名前, セル幅: l名前セル幅,
水平配置: NSLeftTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.1学期試験結果.英語)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.1学期試験結果.数学)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.1学期試験結果.国語)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.1学期試験結果.合計)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.2学期試験結果.英語)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.2学期試験結果.数学)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.2学期試験結果.国語)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅),
PDFテーブルセル(テキスト: "\(試験結果.2学期試験結果.合計)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lデータ線幅)
])
)
v1学期合計 = 合計計算(v1学期合計, 試験結果: 試験結果.1学期試験結果)
v2学期合計 = 合計計算(v2学期合計, 試験結果: 試験結果.2学期試験結果)
}
let l英語平均1 = v1学期合計.0 / vサンプルデータ.count
let l数学平均1 = v1学期合計.1 / vサンプルデータ.count
let l国語平均1 = v1学期合計.2 / vサンプルデータ.count
let l合計平均1 = v1学期合計.3 / vサンプルデータ.count
let l英語平均2 = v2学期合計.0 / vサンプルデータ.count
let l数学平均2 = v2学期合計.1 / vサンプルデータ.count
let l国語平均2 = v2学期合計.2 / vサンプルデータ.count
let l合計平均2 = v2学期合計.3 / vサンプルデータ.count
zテーブルフッタ.append(
PDFテーブル行(列リスト: [
PDFテーブルセル(テキスト: "平均", セル幅: l性別セル幅 + l名前セル幅,
水平配置: NSRightTextAlignment, 枠線: 0.0),
PDFテーブルセル(テキスト: "\(l英語平均1)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l数学平均1)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l国語平均1)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l合計平均1)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l英語平均2)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l数学平均2)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l国語平均2)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅),
PDFテーブルセル(テキスト: "\(l合計平均2)", セル幅: l点数セル幅,
水平配置: NSRightTextAlignment, 枠線: lヘッダ線幅)
])
)
}
@IBAction func PDF作成(sender: AnyObject) {
//PDFドキュメントを生成
let lPDFドキュメント = PDFDocument()
//出力するぺージの制御は全てここで行う
let lページ行数 = 76
let lテーブル行数 = lページ行数 - 6 -
zテーブルヘッダ.count - zテーブルフッタ.count
var vページ番号 = 1
var v開始データNO = 0
while v開始データNO < zテーブルデータ.count {
//ページ出力を繰り返す
var v終了データNO = v開始データNO + lテーブル行数
var vテーブルフッタ:[PDFテーブル行] = []
if zテーブルデータ.count < v終了データNO {
v終了データNO = zテーブルデータ.count - 1
// 最終ページにだけフッタを出力
vテーブルフッタ = zテーブルフッタ
}
//カレントページに出力する PDFテーブル行の配列を作成
let l行リスト = zテーブルヘッダ +
zテーブルデータ[v開始データNO...v終了データNO] +
vテーブルフッタ
//l行リストを持つ PDFテーブルを作成
let lテーブル = PDFテーブル(行リスト: l行リスト)
//PDFページを作成
let lPDFページ = PdfTablePage(ページサイズ: LA4縦, 行数: lページ行数,
マージン上: 10, マージン左: 10, マージン右: 10, マージン下: 10,
ヘッダ: "", フッタ: "", ページ番号: vページ番号, テーブル: lテーブル)
//作成したページをドキュメントに追加
lPDFドキュメント.insertPage(lPDFページ, atIndex: vページ番号-1)
//開始データ番号を1ぺージ分加算
v開始データNO += lテーブル行数
vページ番号++
}
//作成されたPDFドキュメントをファイルに出力
let l出力パス = NSHomeDirectory() + "/pdfTableSample.pdf"
lPDFドキュメント.writeToFile(l出力パス)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment