オープンXMLワークシートに日付を挿入する方法は?
-
04-10-2019 - |
質問
Microsoft Open XML SDK 2を使用していますが、セルに日付を挿入するのに苦労しています。設定して問題なく番号を挿入できます Cell.DataType = CellValues.Number
, 、しかし、私が日付で同じことをするとき(Cell.DataType = CellValues.Date
)Excel 2010 Crashes(2007も)。
設定しようとしました Cell.Text
多くの日付形式とExcelの日付/数値形式に価値があります。また、タイプの属性を削除し、壁に投げた他の多くのピザを削除しようとしました…
ワークシートに日付を挿入する例を教えてもらえますか?
解決
あなたは変換する必要があります DateTime
に double
機能を使用します ToOADate
つまり:
DateTime dtValue = DateTime.Now;
string strValue = dtValue.ToOADate().ToString(CultureInfo.InvariantCulture);
次に、それを設定します CellValue
Cell cell;
cell.DataType = new EnumValue<CellValues>(CellValues.Date);
cell.CellValue = new CellValue(strValue);
使用してセルをフォーマットすることを忘れないでください DateTime
それ以外の場合は、フォーマットが表示されます double
価値、日付ではありません。
他のヒント
Andrew Jが提供するコードを使用しましたが DataType
CellValues.Date
私のために破損したXLSXファイルを生産しました。
DataType
CellValues.Number
私のためにうまくいきました (設定することを忘れないでください NumberFormatId
):
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
私のコード全体:
DateTime valueDate = DateTime.Now;
string valueString = valueDate.ToOADate().ToString();
CellValue cellValue = new CellValue(valueString);
Cell cell = new Cell();
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.StyleIndex = yourStyle; //StyleIndex of CellFormat cfBaseDate -> See below
cell.Append(cellValue);
私の Cellformat スタイルシートのこのセルの場合:
CellFormat cfBaseDate = new CellFormat() {
ApplyNumberFormat = true,
NumberFormatId = 14, //14 is a localized short Date (d/m/yyyy) -> See list below
//Some further styling parameters
};
あなたの日付を別の方法でフォーマットしたい場合、ここにすべてのデフォルトのExcelのリストがあります NumberFormatId
's
ID FORMAT CODE 0 General 1 0 2 0.00 3 #,##0 4 #,##0.00 9 0% 10 0.00% 11 0.00E+00 12 # ?/? 13 # ??/?? 14 d/m/yyyy 15 d-mmm-yy 16 d-mmm 17 mmm-yy 18 h:mm tt 19 h:mm:ss tt 20 H:mm 21 H:mm:ss 22 m/d/yyyy H:mm 37 #,##0 ;(#,##0) 38 #,##0 ;[Red](#,##0) 39 #,##0.00;(#,##0.00) 40 #,##0.00;[Red](#,##0.00) 45 mm:ss 46 [h]:mm:ss 47 mmss.0 48 ##0.0E+0 49 @
リストのソース: https://github.com/closedxml/closedxml/wiki/numberformatid-lookup-table
このリストはclosedxmlからのものであることは知っていますが、OpenXMLでは同じです。
新しいものを作成するとき SpreadsheetDocument
ゼロから、 Date
作業するためのフォーマット、最小限 Stylesheet
作成する必要があります。
重要なのはそれらの数行です:
new CellFormat
{
NumberFormatId = 14,
ApplyNumberFormat = true
})
満杯 Stylesheet
クラス:
using (var spreadSheet = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
// Workbook
var workbookPart = spreadSheet.AddWorkbookPart();
workbookPart.Workbook =
new Workbook(new Sheets(new Sheet { Name = "Sheet1", SheetId = (UInt32Value) 1U, Id = "rId1" }));
// Add minimal Stylesheet
var stylesPart = spreadSheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = new Stylesheet
{
Fonts = new Fonts(new Font()),
Fills = new Fills(new Fill()),
Borders = new Borders(new Border()),
CellStyleFormats = new CellStyleFormats(new CellFormat()),
CellFormats =
new CellFormats(
new CellFormat(),
new CellFormat
{
NumberFormatId = 14,
ApplyNumberFormat = true
})
};
// Continue creating `WorksheetPart`...
後 Stylesheet
追加されます、 DateTime
フォーマットできます:
if (valueType == typeof(DateTime))
{
DateTime date = (DateTime)value;
cell.CellValue = new CellValue(date.ToOADate().ToString(CultureInfo.InvariantCulture));
// "StyleIndex" is "1", because "NumberFormatId=14"
// is in the 2nd item of `CellFormats` array.
cell.StyleIndex = 1;
}
ご了承ください StyleIndex
値はの順序によって異なります CellFormat
のアイテム CellFormats
配列または Stylesheet
物体。この例では NumberFormatId = 14
配列内の2番目のアイテムのアイテム。
OpenXMLに日付を保存する方法は2つあります。数字を書くことによって(使用します ToOADate
)そして設定 DataType
に Number
または書くことによって ISO 8601 フォーマットされた日付と設定 DataType
に Date
. 。デフォルトに注意してください DataType
は Number
したがって、最初のオプションを使用しても、 DataType
.
どちらの方法を選択しても、Excelとしてスタイルを同一に表示するようにスタイルを設定する必要があります。次のコードは、を使用して日付を書く例を示しています Number
フォーマット(明示的に設定する場合となし DataType
)およびISO 8601形式を使用します。
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
//fluff to generate the workbook etc
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet" };
sheets.Append(sheet);
workbookPart.Workbook.Save();
var sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
//add the style
Stylesheet styleSheet = new Stylesheet();
CellFormat cf = new CellFormat();
cf.NumberFormatId = 14;
cf.ApplyNumberFormat = true;
CellFormats cfs = new CellFormats();
cfs.Append(cf);
styleSheet.CellFormats = cfs;
styleSheet.Borders = new Borders();
styleSheet.Borders.Append(new Border());
styleSheet.Fills = new Fills();
styleSheet.Fills.Append(new Fill());
styleSheet.Fonts = new Fonts();
styleSheet.Fonts.Append(new Font());
workbookPart.AddNewPart<WorkbookStylesPart>();
workbookPart.WorkbookStylesPart.Stylesheet = styleSheet;
CellStyles css = new CellStyles();
CellStyle cs = new CellStyle();
cs.FormatId = 0;
cs.BuiltinId = 0;
css.Append(cs);
css.Count = UInt32Value.FromUInt32((uint)css.ChildElements.Count);
styleSheet.Append(css);
Row row = new Row();
DateTime date = new DateTime(2017, 6, 24);
/*** Date code here ***/
//write an OADate with type of Number
Cell cell1 = new Cell();
cell1.CellReference = "A1";
cell1.CellValue = new CellValue(date.ToOADate().ToString());
cell1.DataType = new EnumValue<CellValues>(CellValues.Number);
cell1.StyleIndex = 0;
row.Append(cell1);
//write an OADate with no type (defaults to Number)
Cell cell2 = new Cell();
cell2.CellReference = "B1";
cell2.CellValue = new CellValue(date.ToOADate().ToString());
cell1.StyleIndex = 0;
row.Append(cell2);
//write an ISO 8601 date with type of Date
Cell cell3 = new Cell();
cell3.CellReference = "C1";
cell3.CellValue = new CellValue(date.ToString("yyyy-MM-dd"));
cell3.DataType = new EnumValue<CellValues>(CellValues.Date);
cell1.StyleIndex = 0;
row.Append(cell3);
sheetData.AppendChild(row);
worksheetPart.Worksheet.Save();
}
共有文字列を使用します:
// assuming it's the first item in the shared string table
SharedStringItem sharedStringItem = new SharedStringItem();
Text text = new Text();
text.Text = DateTime.Today.ToString("MM/dd/yyyy hh:mm");
sharedStringTable1.Append(sharedStringItem);
その後、コードで:
// assuming it's the first item in the shared string table
var cell = new Cell {CellReference = "A1", DataType = CellValues.SharedString};
var cellValue = new CellValue("0");
cell.Append(cellValue);
以下は私たちのために働きました:
c.CellValue = new CellValue(datetimeValue).ToOADate().ToString());
c.DataType = CellValues.Number;
c.StyleIndex = StyleDate;
データ型をCellValues.Numberに設定し、Cellformatsから適切なスタイルインデックスを使用してセルをフォーマットしてください。この場合、ワークシート内でスタイルシートを作成し、StyleDateはStyleSheetのCellformatsへのインデックスです。
a)Excel 2007、Excel 2007 Viewerなどとの互換性を取得します。b)1.1.1900の前のdateTimeは文字列として書き込みます。
DateTime dat = (DateTime)dr[dc.ColumnName];
//Not working with Excel 2007
//cell.DataType = CellValues.Date;
//cell.CellValue = new CellValue(dat.ToString("s"));
double diff = (dat - new DateTime(1899, 12, 30)).TotalSeconds / 86400.0;
if (diff > 1)
{
cell.DataType = CellValues.Number;
cell.CellValue = new CellValue(diff.ToString().Replace(",", "."));
if (dat.TimeOfDay == new TimeSpan(0))
{
cell.StyleIndex = 2; //Custom Style NumberFormatId = 14 ( d/m/yyyy)
}
else
{
cell.StyleIndex = 1; //Custom Style NumberFormatId = 22 (m/d/yyyy H:mm)
}
}
else
{
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dat.ToString());
}