サーブレットでMySQLテーブル内をCSVファイルとして出力する方法について

このQ&Aのポイント
  • サーブレット内でMySQLテーブルのデータをCSVファイルとして出力する方法を教えてください。
  • CSVファイルの出力時にBOM(バイトオーダーマーク)を追加する方法を知りたいです。
  • UTF-16LE形式のCSVファイルを正常に出力していますが、BOM有りで出力するにはどうすれば良いでしょうか。
回答を見る
  • ベストアンサー

サーブレット(doGetメソッド内)でMySQLテーブル内を、

サーブレット(doGetメソッド内)でMySQLテーブル内を、 CSVファイルとしてクライアントへダウンロードする以下プログラムで、 UTF-16LE(BOM無し)でCSVファイルが正常に出力されております。 そこでご質問内容なのですが、このCSVを出力する際に、 BOM無しではなくて、 「BOM有り」でCSVファイル出力する(BOMを追加する)方法を教えてください。   ↓ final ResultSetMetaData meta = rs.getMetaData(); (上記のrsは、MySQLテーブル内をSELECTしたレコードセットです) response.setContentType("application/octet-stream;charset=utf-16le"); response.setHeader("Content-Disposition", "attachment; filename=" + "KYOIKU.csv"); out = response.getWriter(); for (int i = 1; i <= meta.getColumnCount(); i++) { out.print("\"" + meta.getColumnName(i) + "\""); out.print(i < meta.getColumnCount() ? "\t" : ""); } out.print("\r\n"); while (rs.next()) { for (int i = 1; i <= meta.getColumnCount(); i++) { out.print("\"" + rs.getString(i) + "\""); out.print(i < meta.getColumnCount() ? "\t" : ""); } out.print("\r\n"); } } catch (final NumberFormatException e) { (以下省略) お世話になります 以上、宜しくお願い致します。

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

> out = response.getWriter(); の後辺りで、BOMを出力したら良いんじゃないでしょうか。 out.print("\uFEFF"); // BOM 出力。 テストしていませんが、こんな感じで、如何でしょう。

hiroasa21
質問者

お礼

「Yanch」様 お世話になっております ご回答通りに試したところ、 おかげ様をもちまして、 「BOMあり」の「UTF-16LE」タブ区切りテキストファイルとして、 CSVファイルを出力出来ました。 本当に助かりました。 ありがとうございました。 PS: なお、今からは、 逆に、 上記で出力したCSVファイルを、 クライアントPC内から、WWWサーバ(CentOS 5.5)内の MySQLテーブルに対して、アップロードする機能を追加予定です。   ↓ MySQL自体が、UTF-8には対応していますが、 残念ながら、UTF-16には未対応の為、 全て今から1つずつ以下の各調査をしながら開発予定です。 いったんWWWサーバにBinaryでアップロードしてから、 BOMを外して、 文字コードを、UTF-16LE(BOM無し)→UTF-8LE(BOM無し)に変換して、 最後に、MySQLインポートコマンド「LOAD DATA INFILE」を利用して、 MySQLテーブルに対して、アップロードする予定です。 出来るだけ、各調査につきましては、 ネットから探してこようと思っておりますが、 今回のように、見つけられなかった場合には、 また、「教えてgoo」でご質問させていただく機会もあるかと存じます。 また機会がございましたら、宜しくお願い致します。 本当にありがとうございました。

関連するQ&A

  • サーブレットとMysqlについて

    画面のtextboxからDB(Mysql)にinsertするときの質問です。 皆さんのおかげでinsertすることができました。 しかし、textboxが一個で値も一つなのに、 insertするとDBには2行同じ値がinsertされます。 下記のソースのどこがいけないのでしょうか? ご教示をお願いします。 「ソース」 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name10 = request.getParameterValues("sonota"); for (int i = 0; i < name10.length; i++) { System.out.println(i + " " + name10[i]); name10[i] = new String(name10[i].getBytes("8859_1"), "UTF-8"); } Connection conn = null; CallableStatement cs = null; PreparedStatement stmt = null; ResultSet rs = null; String url = "jdbc:mysql://localhost/Sample_db"; String dbUser = "root"; String dbPass = "taratara"; try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection(url, dbUser, dbPass); String sql= "insert into Sample_table (name) values (?)"; stmt = conn.prepareStatement(sql); for (String n : name10) { stmt.setString(1, n); stmt.executeUpdate(); } int cnt = stmt.executeUpdate(); stmt.close(); RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); dispatcher.forward(request, response); }catch(Exception e){ } } }

  • サーブレットとMysqlについて

    JSP サーブレット Mysqlについて質問です。 私が今実現させたいことを簡単に説明します。 画面側にはtextboxがあり、このtextboxは追加ボタンによって、 どんどん追加されていきます。 サーブレット側はこのtextboxの全ての値をDBに書き込みたいです。 例えば、textboxが二つなら、一つ目のINSERTでDBのname列にtextbox一個目の値を書き込み、二つ目のINSERTでDBのname列にtextboxニ個目の値を書き込む。 ソースを書いてみたのですが、いろいろと違いがあると思いますので、ご教示をお願いします。 現在は下記ソースを実行してもDBは更新されません・・ もしかしたら、DBの設定がおかしいのでしょうか・・ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name10 = request.getParameterValues("sonota"); for (int i = 0; i < name10.length; i++) { System.out.println(i + " " + name10[i]); name10[i] = new String(name10[i].getBytes("8859_1"), "UTF-8"); } Connection conn = null; CallableStatement cs = null; PreparedStatement stmt = null; ResultSet rs = null; String url = "jdbc:mysql://localhost/Sample_db"; String dbUser = "root"; String dbPass = "taratara"; try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection(url, dbUser, dbPass); String sql= "insert into Sample_db.Sample_table (name) values (name10[i]);"; stmt = conn.prepareStatement(sql); for (String n : name10) { stmt.setString(1, n); stmt.executeUpdate(); } int cnt = stmt.executeUpdate(); stmt.close(); }catch(Exception e){ //exception RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); dispatcher.forward(request, response); } } }

    • ベストアンサー
    • Java
  • MySQLからCSVファイルのダウンロード

    はじめまして。 MySQLのデータをCSVファイルに書き出しダウンロードする場合に、 文字コードをSJISに変換してダウンロードしたいのですが、下記のソースに何を付け加えればできますでしょうか? お手数ですが、何方かご教授よろしくお願いします。 //tab1表から全行を取り出す $sql = "select * from tab1"; if(!$rs = mysql_query($sql)) { print "error=".mysql_errno()."<br>"; exit; } $fields = mysql_num_fields($rs); $rows = mysql_num_rows($rs); //取り出した行数分繰り返す for($i=0;$i<$rows;$i++){ //列数分繰り返す for($j=0;$j < $fields;$j++){ //列の内容出力する print(mysql_result($rs,$i,$j)); //最終列でない場合は カンマ を出力する if ($j < $fields - 1) print(","); } print("\n"); }

    • ベストアンサー
    • PHP
  • PHP+MYSQLで3×5のテーブル表示について

    こんにちは。 PHP+MYSQLでページング処理で画像を出力の勉強をしています。 さっそく質問です。PHP+MYSQLを使って 元テーブルがID番号、名前、性別だとして、 1名分の表示は上記フィールドのデータを縦に3行作った後、 横の列に移るという作業をして、結果縦横に3×5並べる にはどう書けば良いいでしょうか? プログラムのイメージは以下になります。 めくっていく頁のはじめの行($i=$startline)から表示する時、 表示を1列×3行のまとまり□を縦横に3×5出力する場合、 mysqlに接続した後、 $rs = mysql_db_query($db,$sql); while($row=mysql_fetch_array($rs) ){ print("<table><tr>"); print("<td>"); print("<td>"); for($i=0;$i<4;$i++){ print("<tr>"); print("<td>"); print($row[$i]); print("</tr>"); print("</td>"); print("</td>"); } print("</td>"); print("</tr></table>"); こういう形の後、ページングの$pageのurlを作って、$_get[]に 飛ばすというイメージです。 よろしくお願いします。 以上

    • 締切済み
    • PHP
  • CSVファイルのダウンロード時に、パラメータ(Getメソッドで渡される

    CSVファイルのダウンロード時に、パラメータ(Getメソッドで渡される CGI引数(QUERY_STRING環境変数の中身))を、 Javaサーブレット(doGetメソッド内)内で、以下のようにして   ↓ final ResultSetMetaData meta = rs.getMetaData(); response.setContentType("application/octet-stream;charset=utf-16le"); final StringBuffer sbUrl = new StringBuffer(); sbUrl.append("KYOIKU.csv"); sbUrl.append("?").append("20101029162359"); response.setHeader("Content-Disposition", "attachment; filename=" + sbUrl.toString()); out = response.getWriter(); として実行してみたところ、 半角の?(クエスチョンマーク)が、 半角の_(アンダーバー)に変換されて、 テキストファイルとして出力されています。 (KYOIKU.csv_20101029162359) イメージとしては、doGetメソッドからのCSVファイルダウンロード時に、 URLとして、 「http://hogehoge.co.jp/KYOIKU.csv?20101029162359」 として、セット後に実行したいと思っております。 そこでご質問内容なのですが、 ネットで調べていて、先程たまたま、 「URLの末尾にユニークな捨て文字を付加するという手法」として、 「ダウンロードするファイルを、キャッシュにあるファイルとは別物だとIE  に思わせれば、結果的に目的を果たせます。    ↓  (目的とは、CSVファイルのダウンロード時に直接[開く]を押下した場合に、   余計な→[1]文字列が自動的にExcelファイル名として追加されなくなること)」 という記事をたまたま見つけました。 それを試す為に、 「URLの?文字、およびそれ以降の文字列」を、 どのようにすれば、セットできるのか? その方法を教えてください。 お世話になります。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • サーブレット mysqlについて

    JSP サーブレット mysqlについて質問です。 私が今実現させたいことを簡単に説明します。画面側にはtextboxがあり、このtextboxは追加ボタンによって、 どんどん追加されていきます。 サーブレット側はこのtextboxの全ての値をDBに書き込みたいです。 例えば、textboxが二つなら、一つ目のINSERTでDBのagi列にagis1とname列にtextbox一個目の値を書き込み、二つ目のINSERTでDBのagi列にagis2とname列にtextboxニ個目の値を書き込む。 ソースを書いてみたのですが、いろいろと違いがあると思いますので、ご教示をお願いします。 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name = request.getParameterValues("sonota"); Connection conn = null; Statement state = null; int count = 0; try { //コネクション接続 Class.forName("org.git.mm.mysql.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://localhost/Sampl_db", "root", "taratara"); state = conn.createStatement(); String agis = getInitParameter("agis[i]"); for (int i = 0; i < agis.length(); i++) { //クエリ実行 state.executeUpdate( "INSERT INTO Sampl_teble(agi, name) VALUES(" + agis + ", " + name + ")"); } //影響レコード数出力 System.out.println(count); } finally { //ステートメントを閉じる if(state != null) { try { state.close(); } catch (Exception e) { //このエラー処理は「state.close」でエラーが発生した場合でも //下記処理が実行される為に記述しています。 } } //コネクションを閉じる if(conn != null) { conn.close(); } } }

    • ベストアンサー
    • Java
  • MYSQLで読替え(SELECT~CASE)をし、CSVを作成したい

    MYSQLで読替え(SELECT~CASE)をし、CSVを作成したい MYSQLは4シリーズを、PHPは5を使用しています。 データベースの値をCSV出力しようとしておりまして、 下記のようなソースを書いています。 現在このソースで作成されるCSVは 日付|行先/要件|交通機関|往/復|証票|金額 2010/4/5|test| 1 | 1 | 2 | 14480 と、言った感じのものなのですが 交通費(USAGE)や往復(ROUND)、証票(CERTIFICATE) は取得できる数値によって読み替えを行いたいのです。 SELECT~CASE WHEN~END 文で実現できると考え、 phpmyadminで色々ためしているのですが エラー内容は常に #1064 - You have an error in your SQL syntax; で、 ASで項目名を変えている場合、 CASE読み変えはできないのかな等と考えています。 CSVを 日付|行先/要件|交通機関|往/復|証票|金額 2010/4/5|test| 1.電車 | 1.片道 | 2.無し | 14480 と、表示させるにはどう読み替えを行えばよいのでしょうか? 単純にSQL分のミスなのか、そもそもできない事をやろうとしているのか、 いきずまっています。 ---ソースここから--- <?php header("Content-Type: application/octet-stream"); ?> <?php header("Content-Disposition: attachment; filename=output.csv"); ?> <?php $csv_flg = 1; $doc_id = 1; //接続情報  $srv = "localhost";  $id = "aaa";  $passwd = "bbb";  $dbn = "ccc"; /* USAGE は0:未選択,1:電車,2:タクシー */ if($csv_flg == 1){ $sql = "SELECT `REC_DATE`as`日付`, `USAGE`as`行先/要件`, `LINE`as`交通機関`, `ROUND`as`往/復`, `CERTIFICATE`as`証票`, `COST`as`金額` FROM transportation WHERE SEISANSHO_ID = '".$doc_id."' ORDER BY LINE_NO "; $db=mysql_connect($srv,$id,$passwd); mysql_select_db($dbn,$db); $rs=mysql_query($sql,$db); for($i=0; $i<mysql_num_fields($rs); $i++){ print(mb_convert_encoding(mysql_field_name($rs,$i),"SJIS","UTF8").","); } print("\n"); for($j=0 ;$j<mysql_num_rows($rs); $j++) { for($k=0; $k<mysql_num_fields($rs); $k++) { $str=mysql_result($rs,$j,$k); print(mb_convert_encoding($str,"SJIS","UTF8").","); } print("\n"); } mysql_close($db); } ?>

    • ベストアンサー
    • MySQL
  • サーブレット Java 

    サブクラス(内部クラス?)の内容をサーバで表示したいです 一度、同じ質問をしましたが解決できず、再質問いたしました。 ご回答よろしくお願いします。 まず、<jsp:include flush="true" page="/servlet/page.Sflow1"/>を使い jspでサーブレットを表示しています。 サーブレットではサブクラスを使用していますが、そのサブクラスの内容をサーバで表示するにはどうすればいいでしょうか。 以下、そのソースです。 ・・・・ public class Sflow1 extends HttpServlet{ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String sql="select id,c_id,barcode from Flow order by id,c_id,date"; System.out.println("sql="+sql); //中略 HashMap<String,Keiro> hsFlow = new HashMap<String,Keiro>(); String idbk=""; String flowbk=null; while(rs.next()){ String id=rs.getString(1)+":"+rs.getString(2); String flow=rs.getString(3); if(id.equals(idbk)){ if(flowbk!=null){Keiro keiro=hsFlow.get(flowbk);if(keiro == null) keiro = new Keiro(); keiro.addKeiro(flow); hsFlow.put(flowbk,keiro); } } idbk = id; flowbk = flow; } PrintWriter out=response.getWriter(); Object maekeiro[]=hsFlow.keySet().toArray(); Arrays.sort(maekeiro); for(int i=0;i<maekeiro.length;i++){ System.out.println(maekeiro[i]+"からの動き"); hsFlow.get(maekeiro[i]).viewData(); out.println(maekeiro[i]+"からの動き"); } } //中略 class Keiro{ private HashMap<String,Integer> hsNext = new HashMap<String,Integer>(); private int soukei = 0; public void addKeiro(String atokeiro){ Integer i = hsNext.get(atokeiro); if (i==null) i=new Integer(0); hsNext.put(atokeiro,new Integer(i.intValue()+1)); soukei++; } public void viewData(){ Object atokeiro[]=hsNext.keySet().toArray(); Arrays.sort(atokeiro); for(int i=0;i<atokeiro.length;i++){ System.out.println("→"+atokeiro[i]+" "+(hsNext.get(atokeiro[i]).intValue()*100/soukei)+"%"); //このSystem.out.println(・・・)の部分をサーバで表示したいです。 } } } どうすれば標準出力(System.out.println)で表示した内容をサーバで表示することができるのでしょうか? サーブレットを宣言できないのでレスポンスできず・・・(そもそもサブクラスでサーブレットは宣言できるのですか?) 具体的なソース等ご教示お願いいたします。

    • ベストアンサー
    • Java
  • MySQLが動かない(テーブルレコード全表示したい

    初心者です。 いろいろ検索して改善していったつもりですが、なぜ動かないのかどうしてもわからないところがあったので質問させていただいてます。 /* サーバーへの接続 */ $link=mysql_connect($server,$user,$passwd); /* データベース内のテーブルの名前を$tablesに配列で格納 */ $STS = "SHOW TABLE STATUS"; $mytables = mysql_query($STS); while($r = mysql_fetch_array($mytables, MYSQL_ASSOC)){ $tables[] = ($r["Name"]."<br>\n"); } /* 全テーブルのレコードを全てプリント */ foreach($tables as $value){ $results = mysql_query("select * from " . $value, $link); while ($row = mysql_fetch_array($results, MYSQL_ASSOC)) { print_r($row); print("<br>\n"); } } mysql_close($link); foreachの部分を for($i = 0; $i < 2 /*$tables[$i] != 0*/; $i++){ $results = mysql_query("select * from " . $tables[$i], $link); $row = mysql_fetch_array($results, MYSQL_ASSOC); print_r($row); } でもやってみました。 これを利用して、何とか表形式でデータベースのテーブルのレコードをwebページに出力させようと思っています。 実行するとprint_r($row)の出力がでず、いろいろ試してみた結果、$resultsもしくは$rowに問題があることがわかりました。 var_dump($row); でNULLが出力されました。 var_dump($results); もやったのですが、うろ覚えなのでここには書きません。 $results = mysql_query("select * from gutaiteki_table", $link); としたら動いたので、select * from の後に変数を続けているからだめなのかなと思いましたが、私にはどうにもしようがありません。 これを正常に動作させる方法、他にうまいやり方があればその方法を教えてほしいです。 (私はデバッグのやり方がわからないので、「改変してwebのページを更新する」というのを繰り返してプログラムを作成していますが、他に方法があればそれも併せてご意見ほしいです。これは余裕があったらで構いません。)

  • MySQL5のデータを、SQL文を使いcsv形式でダウンロードさせると文字化けします

    環境:Apache2&PHP5&MySQL5 MySQL5のデータを、SQL文を使いcsv形式でダウンロードさせると文字化けします。 -- <?php header("Content-Type: application/octet-stream"); ?> <?php header("Content-Disposition: attachment; filename=output.csv"); ?> <?php $srv = "localhost"; // サーバー名 $id = "root"; // ユーザーID $passwd = "******"; // パスワード $dbn = "sample"; // データベース名 $sql = "SELECT * FROM result"; // SQL文 $db=mysql_connect($srv,$id,$passwd); mysql_select_db($dbn,$db); $rs=mysql_query($sql,$db); for($i=0; $i<mysql_num_fields($rs); $i++){ print(mb_convert_encoding(mysql_field_name($rs,$i),"SJIS","EUC-JP").","); } print("\n"); for($j=0 ;$j<mysql_num_rows($rs); $j++) { for($k=0; $k<mysql_num_fields($rs); $k++) { $str=mysql_result($rs,$j,$k); print(mb_convert_encoding($str,"SJIS","EUC-JP").","); } print("\n"); } mysql_close($db); ---ダウンロードしたCSVは半角英数文字はそのまま出ますが、 日本語(全角)が、?に化けます。(下記の参照してください) 24 2 1 444 4444 2008/7/3 15 ? 1E+18 ??? ????? ?????? 25 2 1 444 kojiide 2008/7/3 30 ? 1E+18 ??? ????? ?????? 26 2 1 444 kojiide 2008/7/3 30 ? 1E+18 ??? ????? ?????? --- print(mb_convert_encoding($str,"SJIS","EUC-JP").","); でSJISになっていると思うのですが、どなたかアドバイスいただけると幸いです。

    • ベストアンサー
    • PHP

専門家に質問してみよう