2016-01-19 16 views
5

ColdFusion 11では、cfSpreadsheetを使用して.xlsファイルをクエリオブジェクトに変換しています。ここに私のデモのスプレッドシートのスクリーンショットです:cfSpreadsheet 2桁の年

screenshot of spreadsheet

私は、すぐにそれが作成されるクエリオブジェクトを表示するには、このコードを使用します。

<cfspreadsheet action="read" src="demo_spreadsheet.xls" 
     excludeHeaderRow="true" 
     headerrow="1" query="demo_query"/> 
<cfdump var="#demo_query#"> 

...と私はこれらの結果を得ます:

png showing dump of query object

スプレッドシートからの私の4桁の年のすべてが、今2桁の年であることに注意してください?私はこのコードを使用してクエリオブジェクトにデータを出力する行くとき:

<ul> 
<cfoutput query="demo_query"> 
    <li>#name# - #dateformat(start_date, 'medium')#</li> 
</cfoutput> 
</ul> 

を...私は(次の出力を取得し[OK]を、私はここに新しいので、私は以上の2つのスクリーンショットを投稿することはできませんあなたは、このコピー/貼り付け)に私を信頼する必要があります:

  • アルファ - 2007年1月1日
  • ブラボー - 1972年2月2日
  • チャーリー - 2017年3月3日
  • デルタ - 1984年4月4日
  • エコー - 2029年12月31日
  • フォックストロット - 1930年1月1日
  • ゴルフ - 1930年1月1日

年1907年は今2007年、1917年で今2017年、1929年で今2029年、および2030です今は1930年です。1930年1月1日以前の年の年は20xxと読み込まれ、12月31日以降は2029年が19xxとして読み込まれます。

何か不足していますか?私はY2Kでこのようなことを考え出したと思った。私が間違っている場所に簡単な設定がありますか?私はこの問題の話を知りました。それについては何も見つかりません。

アドバイスは大歓迎です。

+0

、私は異なる結果を得ました。 m/d/yyyy形式の文字列の場合、何も変更されませんでした。 yyyy-mm-dd形式の文字列があなたの質問に従って変更されました。 ColdFusionを実行しているマシンおよび/またはスプレッドシートを作成したマシンの地域設定と関係している可能性があります。 –

+0

ソーススプレッドシートでは、実際に日付が4桁で入力されたのか、データをフォーマットするだけのセルですか? –

+0

Miguel-F - はい、毎年4桁の数字を入力しました。デフォルトの地域設定が原因と思われます。 –

答えて

4

ほとんどの場合、スプレッドシートのセルに組み込まれているregional format *m/d/yyが使用されている可能性があります。表示された値(この場合は「読み取り」)は使用する環境やクライアントによって異なる場合があります。アスタリスク(*)で始まる

日付と時刻の形式は コントロールパネルで指定されている地域の日付と時刻の設定で 変化に対応します。アスタリスクのない形式は、コントロール パネル設定の影響を受けません。

これは、cfspreadsheetで起こっているようです。 Excelでの2桁ではなくの数字が2桁で表示される理由はわかりません。フォーマットは*m/d/yyです。ただし、CF/POIはExcelの仕様に従って正しい結果を返しています。あなたはm/d/yyyyすなわち、非地域、4桁の年にセルの書式を切り替えた場合、出力はあなたが期待したものであることに注意してください:

Comparison of regional and non-regional formats Non-regional Date Format

更新:あなたのCFコードが異なる歳未満の表示理由として、あなたが期待していたのは、あいまいな日付文字列がCFによってどのように処理されたかによるものです。 CFSpreadsheetによって返されたクエリには文字列が含まれていますが、日付オブジェクトは含まれていないことに注意してください。これらの文字列をDateFormatに渡すとき、CFは最初に文字列を解釈して日付オブジェクトに変換してから、日付マスクを適用する必要があります。

米国 ロケール規則に従ってフォーマットされた日付/時刻値を含む文字列を次のようAccording to CF's rulesは、2桁の年が解釈されます。日付/時刻を100 AD-9999 ADの範囲で表すことができます。 0〜29歳は2000〜2029年と解釈されます。 30-99歳は で、1930-1999年と解釈されます。

正直なところ、CFSpreadsheetは、多くの鐘や笛を使わずにスプレッドシートを読み書きする簡単な方法を提供するように設計されています。 AFAIKでは、セル値の解釈方法の変更はサポートされていません。 4桁の年を強制する場合は、手動またはプログラムによる非地域日付形式を使用するようにスプレッドシートを変更する必要があります(つまり、スプレッドシートをCFで読み込み、新しいセル形式を適用する)。これはおそらく最も簡単なオプションです。

さらにコードの柔軟性を望む場合は、cfspreadsheetではなくspreadsheet functionsを使用することもできます。この特定のケースでは、私は彼らにも必要な機能が欠けていると思います。したがって、基になるPOIライブラリと少しのJavaコードを使用して調べることができます。 This threadは、スプレッドシートのセルと値に関するすべての種類の詳細を取得する方法を示しています。それは簡単に独自のクエリや値を含む構造、フォーマット、エトセトラの配列を作成するように変更することができます

Array of structures containing cell data

コード:バージョン9で

<cfscript> 
// get the sheet you want to read 
cfSheet = SpreadSheetRead("c:/temp/demo_spreadsheet.xls"); 
workbook = cfSheet.getWorkBook(); 
sheetIndex = workbook.getActiveSheetIndex(); 
sheet = workbook.getSheetAt(sheetIndex); 

// utility used to distinguish between dates and numbers 
dateUtil = createObject("java", "org.apache.poi.ss.usermodel.DateUtil"); 

// process the rows and columns 
rows = sheet.rowIterator(); 
while (rows.hasNext()) { 
    currentRow = rows.next(); 
    data = {}; 

    cells = currentRow.cellIterator(); 
    while (cells.hasNext()) { 
     currentCell = cells.next(); 

     col = {}; 
     col.value = ""; 
     col.type = ""; 
     col.column = currentCell.getColumnIndex()+ 1; 
     col.row = currentCell.getRowIndex()+ 1; 
     col.format = currentCell.getCellStyle().getDataFormatString(); 



     if (currentCell.getCellType() EQ currentCell.CELL_TYPE_STRING) { 
       col.value = currentCell.getRichStringCellValue().getString(); 
      col.type = "string"; 
     } 
     else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_NUMERIC) { 
      if (DateUtil.isCellDateFormatted(currentCell)) { 
       col.value = currentCell.getDateCellValue(); 
       col.type = "date"; 
      } 
      else { 
       col.value = currentCell.getNumericCellValue(); 
       col.type = "number"; 
      } 
     } 
     else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_BOOLEAN) { 
      col.value = currentCell.getBooleanCellValue(); 
      col.type = "boolean"; 
     } 
     // ... handle other types CELL_TYPE_BLANK, CELL_TYPE_ERROR, CELL_TYPE_FORMULA 

     data["COL"& col.column] = col; 
    } 

    // this row is finished. display all values 
    WriteDump(data); 
} 
</cfscript> 
+0

情報ありがとうございます。アップロードする前にスプレッドシートにセルの書式を設定していなかったので、日付を入力すると4桁の数字が入力されました。 2桁の年がExcelの既定の形式であるように見えます。あなたが記述したようにスプレッドシートのセルフォーマットを変更したとき、私はクエリオブジェクトに期待される結果を得ました。それは非常に奇妙なので、2つだけを渡しながらExcelは4桁の数字をすべてユーザーに表示します。それはExcelのバグですか? 私は、ユーザーが日付の列の書式を手動で変更することは合理的に期待できないため、提案する回避策を開発する必要があります。 –

+0

これはデフォルトです。おそらく下位互換性のためです。あなたが言うバグ?私はMSがそれを投稿2Kの "機能"と呼んでいると確信しています;-) – Leigh

+0

* Excelは4つの数字すべてをユーザーに表示しますが、実際には2つだけを渡します*実際はあなたのcfoutputが異なる理由を意味する場合、私が上で説明したよりも。cfspreadsheetは日付オブジェクトではなく*文字列*を返します。これらの文字列を 'date_format()'に渡すとき、CFはまずそれらを独自の規則に従って日付オブジェクトに変換する必要があります。だから、CFは1/1/30をExcelではなく2030年ではなく1930年と解釈させているのです。回答を更新しています。 – Leigh

関連する問題