カテゴリーアーカイブ 言語

村上 著者:村上

【PHP】PHPExcelでグラフ入りのテンプレートを使用する方法

以前、「【PHP】PHPExcelを使うときにセルの書式設定を変更する方法」という記事を投稿しましたが、本日の記事は、またこの PHPExcel について。
今回は、PHPExcelでテンプレートファイルを使う際に、グラフが入っていた場合の処理についてまとめです。

今回参考にした投稿はこちら。

PHPExcelでテンプレートファイルからグラフを作ってみよう – Qiita
https://qiita.com/tutida/items/2d163ed7662bb499a082

やりたいことがすべて書いてありました…!

 

早速、コードを書いていきますが、PHPExcelオブジェクト生成から、シートの選択まではこんな感じ

// PHPExcelオブジェクトを生成する
$book = new PHPExcel();
$objReader = PHPExcel_IOFactory::createReader('Excel2007');
// 読み込むテンプレートファイルにグラフが含まれていることを宣言
$objReader->setIncludeCharts(TRUE);
// テンプレート読み込み
$book = $objReader->load('テンプレートのエクセルファイルのパス');
$book->setActiveSheetIndex(0);
// カレントシート選択
$sheet = $book->getActiveSheet();

上記のコードで重要なのは、5行目の「読み込むテンプレートファイルにグラフが含まれていることを宣言する」、という

$objReader->setIncludeCharts(TRUE);

上記の記述です。
この一行を入れないと、読み込んだテンプレートファイルからグラフが消えてしまいます。

また、読み込み時だけでなく、下記のようにエクセルファイルの出力・保存の時にも同じ記述を入れる必要があります。

// ファイル名
$filename = 'PHPExcel-sample.xlsx';
$writer = PHPExcel_IOFactory::createWriter($book, 'Excel2007');
// 書き出すエクセルファイルにグラフが含まれていることを宣言
$writer->setIncludeCharts(TRUE);
$writer->save("/tmp/".$file);
File::download("/tmp/".$file, $file);

こんな感じ。
出力時にも、エクセルファイルにグラフが含まれていることを宣言する5行目の記述を必ず入れましょう。

 

ただ、グラフを扱う際には注意が必要で、あまり複雑な指定をすると、グラフが含まれていることを宣言していてもグラフが消える場合があります。
現に、私もそれで悩まされています。
グラフ入りのテンプレートを入れる場合は、極力簡単でシンプルなものを使うようにしましょう。

なお、グラフが消える・簡略化される条件は下記のようなものがあげられるとのこと。

  • X軸を設定している
  • Y軸を2種類設定している場合、2つ目は消える
  • 詳細な設定はほぼ消える

…かなり簡単なものしか扱えなさそうですね。
これならいっそ、テンプレートから読み込まず、PHPExcelでグラフを作成したほうがいいかもしれません。

ゼロからグラフを作成する方法については、冒頭で挙げた投稿を書かれた方が記事を挙げているので、こちらが参考になるかと思います。

PHPExcelでゼロからグラフを書いてみよう – Qiita
https://qiita.com/tutida/items/643baa8832beedd53499

  • この記事いいね! (0)
村上 著者:村上

【jQuery】要素を削除する.remove()と.empty()の違い

JavaScriptで要素を削除するメソッドに、.empty().remove()があります。
どちらも要素を削除する、という点では同じなのですが、挙動が少し違うので、これを機にまとめてみました。

.remove()
こちらは単純に指定した要素そのものを削除します。
例としては下記のように要素が指定されていた時に、

<ul id="list01">
    <li id="item01">item01</li>
    <li id="item02">item02</li>
    <li id="item03">item03</li>
</ul>
/* javascript */
$("#item01").remove();

上記のJavaScriptを実行すると、idに「item01」が指定された li 要素が削除されるというもの。
指定する要素は、id だけでなく、勿論classでもOKです。
なお、class を指定した場合は、一致する class がすべて削除されます。

 

.empty()
こちらは指定した要素の中にある子要素を削除します。
サンプルコードは下記の通り。
id に「list01」が指定された ul 要素に対して、.empty() メソッドを指定すると、ul の子要素である li がすべて削除されます。

<ul id="list01">
    <li id="item01">item01</li>
    <li id="item02">item02</li>
    <li id="item03">item03</li>
</ul>
/* javascript */
$("#list01").empty();

.empty() メソッドについては、「指定した要素の中身を空にする」と覚えるとわかりやすいかな。
なお、あくまでも指定した要素の子要素を削除するメソッドなので、指定した親要素自身は残ります。

 

簡単にではありますが、大きな違いはこんな感じ。
.remove() は単純明快なので、ある特定の要素を消す、というときに使用します。
一方で .empty() については、一度リストなどを再描画する際、ul などは残しつつ、リストの項目である li だけを削除する、というときに使えます。
以前投稿した、要素を追加するメソッドとセットで覚えるのがおすすめですね。

【備忘録】jQueryの要素追加のメソッド一覧
https://cpoint-lab.co.jp/【備忘録】jqueryの要素追加のメソッド一覧/

特に .empty() については、.append() とセットで覚えると、様々な処理やより扱いやすいかと思います。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】指定した文字に一致したすべての文字を置換する方法

少し久しぶりな気がするJavaScriptネタ。
今回は、これまた業務中に質問された、文字列の置換について。
自分でも少しハマりやすいと思った点なので、おさらいもかねてまとめます。

 

文字列を置換するには、.replace() というメソッドを使います。
使い方は下記の通り。

var text = "あいうえお";
var replaceText = text.replace("あ","か");
document.write(replaceText);

こちらを実行した結果は、「かいうえお」となります。
変数text内の「あ」が「か」に置換されました。

 

で、ハマるポイントはここから。
上の例のように、置換したい文字が文字列に1つしかない場合はこちらでも問題ないのですが、置換したい文字が文字列の中に複数あった場合は、この方法ではうまくいきません。

例としては下記の通り。

var text = "あああああ";
var replaceText = text.replace("あ","か");
document.write(replaceText);

上記のコードを実行した結果は、「かああああ」となり、一番最初の「あ」しか置換されていません。
これを防ぐためには、正規表現を使うか、RegExpオブジェクトを使う方法があります。

 

まず、正規表現を使う方法は下記のとおり。

var text = "あああああ";
var replaceText = text.replace(/あ/g,"か");
document.write(replaceText);

こちらを実行すると、すべての「あ」が「か」に置換され、「かかかかか」と出力されます。

次に、RegExpオブジェクトを使う方法について。
RegExpは、正規表現用のオブジェクトであるとのこと。
あまり使ったことはないのですが、正規表現が苦手!という人にはこちらの方がわかりやすいのかも?

なお、下記の二つは同じ意味になります。

var regExp = /あ/g ;
var regExp = new RegExp( "あ", "g" ) ;

そして、RegExpを使ったコードの例は下記の通り。

var text = "あああああ";
var targetStr = "あ" ;
var regExp = new RegExp( targetStr, "g" ) ;
var replaceText = text.replace(regExp,"か");
document.write(replaceText);

こちらも実行した結果は「かかかかか」となります。

 

.replace()メソッドは便利ではありますが、単に文字列を指定するだけだと、最初にヒットした文字列しか置換されない、という点が要注意ですね。
久しぶりに使ったときは、この癖を忘れていて改めて調べ直してしまいました。
正規表現を使うという点が、苦手意識を持っている人には少しだけネックかもしれませんが…。
なお私はよく「正規表現チェッカー」というサイトで正規表現が正しいかどうか確認します。
ページ下部にリファレンスも載っているのでお勧めです。

正規表現チェッカー PHP: preg_match() / JavaScript: match()
http://okumocchi.jp/php/re.php

  • この記事いいね! (0)
村上 著者:村上

【CSS】意外と使える背景画像のサイズを変更する方法

大した技術ではないのですが、個人的に使えると思ったのでご紹介。
タイトルにある通り、CSS の background-image で指定した画像のサイズを変更する方法です。

コードはこちら。

// 背景画像を 30px × 30pxに指定
background-image:url("背景画像のパス");
background-size:30px;

そのものずばり、background-size というプロパティを使います。
上記のコードを追加すると、背景に指定した画像のサイズが縦横30pxで表示されます。

また、上記のようにサイズをじかに指定する以外にも、パーセント指定や、containcover といった値も使用できます。
パーセントの場合は、背景画像が指定された範囲に対する画像の幅と高さをパーセンテージで指定できます。
containは、画像の縦横の比率は保持して、背景の範囲に収まる最大サイズになるように画像を拡大縮小してくれます。
coverは、画像の縦横の比率を保持するところまでは、contain と同じですが、こちらは背景の範囲を完全に覆う最小サイズになるように画像を拡大縮小してくれます。
用途によって使い分けてください。

なお、画像のサイズを、縦20px 横 40pxなど、正方形でないサイズで指定したいときは、下記のように指定します。

// 背景画像を 縦20px 横 40pxに指定
background-image:url("背景画像のパス");
background-size:40px 20px;

横のサイズ 縦のサイズ、の順番で記載します。

 

今回は、グラフのマス目を背景画像を指定して表現するというときに、このプロパティを利用しました。
background-size を使えば、マス目の大きさを変えたいときに、元画像自体を編集することなく、CSSのみで調整することができます。
ちょっとしたことですが、意外と汎用性が高そうです。

  • この記事いいね! (0)
村上 著者:村上

【CSS】要素に指定した position: fixed が効かない時の対処法

そこまで長時間悩んだわけではないのですが、ちょっぴりハマったのでご紹介。

とある要素に、下記のようにCSSを指定していたのですが、スクロールした際に、親要素の下部にくっついて動くような挙動になってしまいました。

position: fixed;
bottom: 0;
left: 0;

本来は画面の下部にくっついて動かないでいてほしかったのですが、気が付けばページ自体に追従する形になっており、そこそこ慌てました。
が、親要素を確認しても、特に変な記述は見つからず…。

 

で、色々調べてみたところ、bodyに指定した下記のCSSが原因でした。

transform: translateZ(0);

親要素ばかりみていたので、これは盲点でした。

どうやら、子要素に position: fixed を指定した時、親要素に transform が指定されていると、position: fixed が希望した通りの挙動をしてくれなくなるみたいでした。

対処法としては、body に指定した transform を削除するか、下記のように !important を用いて無理矢理上書きするかですね。

// transform: translateZ(0);
// transform を解除

transform: none !important;
// !important を使って none で強制的に上書き

力業感が否めませんが…正常に動くようになったので、今回はこれで問題なしということにしておきます。

position を指定した要素の挙動がおかしくなった場合は、親要素もしくは body に transform が指定されていないか確認してみてください。

  • この記事いいね! (1)
村上 著者:村上

【未解決】Xcode 9.1 で ‘Cordova/CDVViewController.h’ file not found というエラーが発生

Cordova で開発中のアプリをビルドしようとしたところ、下記のようなエラーが発生しました。

MainViewController.h:28:9: ‘Cordova/CDVViewController.h’ file not found

エラー内容は書いてある通りで、MainViewController.h というファイルで、Cordova/CDVViewController.h が見つからないというものでした。
MainViewController.h を確認してみると、確かに #import <Cordova/CDVViewController.h> の行でエラーとなっていました。

 

解決方法を調べたところ、下記の画像のように、Build SettingsHeader Search Path の値に下記のような記述があるので、

"$(OBJROOT)/UninstalledProducts/include"

こちらを、

"$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include"

上記に変更すれば、実行できますとの書き込みを見つけたので、早速試してみました。

が、今回のエラーはこちらでは解決できませんでした…!
以前も全く同じエラーに遭遇したことがあり、その時はこのやり方で解決できたのですが、今回は何故かダメでした。
他にも、iOSのプラットフォームを一度削除した後、再度追加するとビルドできるとの記載もあったのですが、こちらも効果なし…。
それ以外の解決方法も検索してはいるのですが、ほぼ Build Settings > Header Search Path の値を修正するという解決策しかヒットしないので、正直手詰まりです。

もし、上記以外の解決策をご存知の方は、是非ともご教授くださいませ。
どうぞよろしくお願い致します。

  • この記事いいね! (4)
takahashi 著者:takahashi

モバイル版Chrome/SafariでWebページをWebアプリケーション表示させる方法

高橋です。

モバイル版のChromeやSafariには、特定のページのショートカットを作る機能がついています。

使ったことがある方もいらっしゃるのではないでしょうか?
僕もキャリアが提供するWebメールなどで、画面をすぐに開けるようにするためによく使っています。

さて、このショートカットを作る機能ですが、サイトによって動作が異なることはご存知でしょうか?
例えば、ショートカット化したAmazonのショッピング画面を開くと、

こんな感じで通常のブラウザ画面で表示されます。
一方、Softbank のS!メールどこでもアクセス をショートカット化すると…

開いたときにスプラッシュ画面が!

ブラウザのアドレスバーの表示も消え、まるでアプリのような見た目になりました。

この表示の違いは、対象のページのheadタグに次のようなmetaタグが入っていると起こります。

<head>
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="サイト名">
</head>

この2行を入れておくと、モバイル版のSafari、Chromeで作成したショートカットから起動すると、URLバーが消え、アプリのような表示になるというわけです。
もし、スマホ・タブレット向けに作っているページがあり、Webアプリとして使ってほしい、URLバーを消した状態で使ってほしい、というときに便利です。

一方で、ブラウザ側でこの切替を行う設定は今のところないようなので、ユーザー側ではコントロールを行うことができません。
この点は注意が必要そうです。

モバイル用のWebアプリを作成している方は、一度試してみてはいかがでしょうか。

  • この記事いいね! (0)
村上 著者:村上

【PHP】DateTimeで現在日時から○日後の日付を取得する方法

後輩に聞かれたので、私と彼のための覚え書きのメモとして。

PHPには、日付と時刻を扱う DateTimeクラスがありますが、こちらを用いて、現在の日時から○日後や、○時間前の日付・時刻を取得する方法です。

DateTimeクラスについて、PHPのマニュアルはこちらから。

DateTime クラス – Manual
http://php.net/manual/ja/class.datetime.php

 

○日後を扱う前に、まず現在の日時を取得する方法は下記の通り。

// 現在の日時を取得
$now = new DateTime();
echo $now->format('Y-m-d H:i:s'); // 2017-12-05 19:05:00

DateTimeの引数を空で指定すると、現在の日時を取得できます。
それを任意のフォーマットに変換しています。

また日付文字列を引数に指定する事も出来ます。

// 日付文字列で指定した日時を取得
$date = new DateTime("2017-06-01 06:00:00");
echo $date->format('Y-m-d H:i:s'); // 2017-06-01 06:00:00

日付文字列で指定した日時を取得できます。

 

で、本題はここから。
○日後という相対的な日時を取得したい場合、modify というものを使うことにより、DateTimeで取得した日付を変更できます。

// 現在の日時の1日後の日時を取得
$date = new DateTime();
$date->modify('+1 day');
echo $date->format('Y-m-d H:i:s');  // 現在の日時の1日後の日付

または、この書き方でもOK。

// 日付文字列で指定した日時の1日後の日時を取得
$date = new DateTime("2017-06-01 06:00:00 + 1 day");
echo $date->format('Y-m-d H:i:s'); // 2017-07-01 06:00:00

上記はGoogle Chromeでしか動作検証していませんが、1日後の日付が正しく取得できました。

それ以外にも、「– 1 day」と書けば1日前、「+ 3 hour」と書けば3時間後、「+ 1 week」と書けば1週間後の日時がそれぞれ取得できます。
日付の変更は、使用頻度はそこまで高くはないのですが、ふとした拍子に使ったりするので、頭の片隅ででも覚えて置きたいですね。

 

また、今回 DateTimeクラスを調べていて知ったのですが、数値を指定して日時を取得することもできるとのこと。
このやり方については私はまだ実際に使ったことありません。

// 数値を指定して日時を取得
$date = new DateTime();
$date->setDate(2017,6,1);
$date->setTime(6,0,0);
echo $date->format('Y-m-d H:i:s'); // 2017-06-01 06:00:00

セレクトボックスから年・月・日をそれぞれ選んで、それらを日付に変換するときとかに使えそうですね。
が、今回はDatepickerを使っているので、使うことはなさそうです。

  • この記事いいね! (0)
村上 著者:村上

【未解決】FuelPHPでストアドプロシージャを実行してデータを取得したい

タイトルにある通り、今回の記事はまだ未実装、というか実現できていないことについて。
ということで、もし解決策をご存知の方がいらっしゃれば、何卒ご教授くださいますようお願い致します。

 

ストアドプロシージャについては、こちらの記事がわかりやすいかと。

ストアドプロシージャの基本的ななにか – Qiita
https://qiita.com/setsuna82001/items/e742338eb93e3a48ba46

こちらの記事によると、ストアドプロシージャとは「データベース上での一連の処理に、名前をつけて関数のように呼び出して使用できるもの」とのこと。
データベース上で動作が完結するので、開発言語に依存しません。

 

FuelPHPについて、公式サイトはこちらから。

FuelPHPドキュメント
http://fuelphp.jp/docs/1.7/

FuelPHPは、PHP5.3以上を対象に開発されたWebフレームワークです。
他のフレームワークに比べて規約が少なく、また高速で軽量なため、使いやすいのが特徴です。

こちらのサイトもご参考に。

高速で軽量なフレームワークFuelPHPを使う
http://www.buildinsider.net/web/bookphplib100/096

 

そして、今回実現したいのは、この両方を利用して、データベースからデータを取得する方法についてです。
実行するストアドプロシージャはこんな感じ。

1> EXEC dbo.user_month_report @year =2017, @month =12;
2> go

※実際に動作させているものとは異なります。

こちらをターミナルで実行すると、望んだとおりの結果が得られます。
したがって、ストアドプロシージャ自体には問題はなさそう。

が、こちらを下記のように FuelPHP で実行すると、結果が何故か bool(true) が返ってきます。

$result = DB::query("EXEC dbo.user_month_report @year =2017, @month =12;");
$result->execute();

ストアドプロシージャに問題がないようなので、十中八九 FuelPHP が原因というのは分かるのですが、その解決策がどうしてもわかりません。
FuelPHPのドキュメントにも、ストアドプロシージャの実行方法についての記述がないため、そもそも対応していないのでしょうか。

ちなみに、FuelPHPのフォーラムに、「DB Class with mysql – select from stored procedure」という、今回の状況に似たような投稿があったのは見つけました。
その中で、DB::query()の第二引数の$typeに SQL クエリタイプとして「DB::SELECT」を指定するといいとの記述があったので試してみましたが、残念ながら結果は変わりませんでした。

参考にしたフォーラムの投稿はこちら。

DB Class with mysql – select from stored procedure
https://fuelphp.com/forums/discussion/4299

 
新しいライブラリやフレームワークを使うのは、やはり難しいですね。

  • この記事いいね! (0)
村上 著者:村上

【CSS】DIV要素を上下左右で中央揃えする方法(IE、Safari対応)

使用頻度は高めだけど、良く忘れるので備忘録として。
今回は今回は子要素を上下左右で中央揃えにするやり方について。
なお、同じ方法で画像の中央揃えも実現できます。

HTML、CSSのコードはこんな感じ。

<!-- HTML -->
<div id="parent">  <!-- 親要素 -->
    <div id="child"></div>  <!-- 子要素 -->
</div>
/* CSS */
#parent {
    background-color: blue;
    height: 200px;
    width: 200px;
    position: relative;
}
#child {
    background-color: green;
    height: 100px;
    width: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -moz-transform: translate(-50%, -50%);
}

このとき重要となってくるのが、親要素に指定された position: relative; と、子要素に指定された position: absolute; です。
これがあることで、子要素が表示される際の基準位置が親要素の左上となります。

そして、子要素の top、left をそれぞれ50%とすることで、子要素の左上の位置を親要素の中央に来るようにしています。
が、これでは左下に移動しすぎなので、transform: translate(-50%, -50%); で子要素の縦横それぞれの50%分だけ左上に移動させて、ちょうど親要素の上下中央に子要素が来るように調節しています。

 

やっていることは以上です。
他にも上下中央揃えする方法はあるようですが、今回の書き方を使ったところ、IESafariなど、表示が崩れやすいブラウザで表示した時に崩れなかったので、個人的にはおすすめの書き方です。
IEやSafariでデザイン崩れに悩まされている場合は、こちらの書き方をお試しになってみてはいかがでしょうか。

  • この記事いいね! (0)