有没有人碰巧知道,如果有一个令牌,我可以添加到我的csv的某个字段,这样Excel就不会试图将它转换为日期?
我试图从我的应用程序中编写一个.csv文件,其中一个值碰巧看起来足够像一个日期,Excel会自动将它从文本转换为日期。我曾尝试将所有文本字段(包括看起来像日期的文本字段)放在双引号内,但没有效果。
有没有人碰巧知道,如果有一个令牌,我可以添加到我的csv的某个字段,这样Excel就不会试图将它转换为日期?
我试图从我的应用程序中编写一个.csv文件,其中一个值碰巧看起来足够像一个日期,Excel会自动将它从文本转换为日期。我曾尝试将所有文本字段(包括看起来像日期的文本字段)放在双引号内,但没有效果。
当前回答
我知道这是个老话题了。对于像我这样的人来说,通过PowerShell COM对象使用Office 2013仍然有这个问题,可以使用opentext方法。问题是这个方法有很多参数,有时是相互排斥的。要解决这个问题,您可以使用本文介绍的invoke-namedparameter方法。 一个例子是
$ex = New-Object -com "Excel.Application"
$ex.visible = $true
$csv = "path\to\your\csv.csv"
Invoke-NamedParameter ($ex.workbooks) "opentext" @{"filename"=$csv; "Semicolon"= $true}
不幸的是,我刚刚发现当单元格包含换行符时,该方法会以某种方式破坏CSV解析。这是CSV支持的,但微软的实现似乎有bug。 此外,它不知何故没有检测到德语特有的字符。给它正确的文化并没有改变这种行为。所有文件(CSV和脚本)都使用utf8编码保存。 首先,我编写了以下代码,逐个单元插入CSV。
$ex = New-Object -com "Excel.Application"
$ex.visible = $true;
$csv = "path\to\your\csv.csv";
$ex.workbooks.add();
$ex.activeWorkbook.activeSheet.Cells.NumberFormat = "@";
$data = import-csv $csv -encoding utf8 -delimiter ";";
$row = 1;
$data | %{ $obj = $_; $col = 1; $_.psobject.properties.Name |%{if($row -eq1){$ex.ActiveWorkbook.activeSheet.Cells.item($row,$col).Value2= $_ };$ex.ActiveWorkbook.activeSheet.Cells.item($row+1,$col).Value2 =$obj.$_; $col++ }; $row++;}
但这太慢了,所以我找了个替代品。显然,Excel允许您使用矩阵设置单元格范围的值。所以我在这篇博客中使用算法将CSV转换为一个多数组。
function csvToExcel($csv,$delimiter){
$a = New-Object -com "Excel.Application"
$a.visible = $true
$a.workbooks.add()
$a.activeWorkbook.activeSheet.Cells.NumberFormat = "@"
$data = import-csv -delimiter $delimiter $csv;
$array = ($data |ConvertTo-MultiArray).Value
$starta = [int][char]'a' - 1
if ($array.GetLength(1) -gt 26) {
$col = [char]([int][math]::Floor($array.GetLength(1)/26) + $starta) + [char](($array.GetLength(1)%26) + $Starta)
} else {
$col = [char]($array.GetLength(1) + $starta)
}
$range = $a.activeWorkbook.activeSheet.Range("a1:"+$col+""+$array.GetLength(0))
$range.value2 = $array;
$range.Columns.AutoFit();
$range.Rows.AutoFit();
$range.Cells.HorizontalAlignment = -4131
$range.Cells.VerticalAlignment = -4160
}
function ConvertTo-MultiArray {
param(
[Parameter(Mandatory=$true, Position=1, ValueFromPipeline=$true)]
[PSObject[]]$InputObject
)
BEGIN {
$objects = @()
[ref]$array = [ref]$null
}
Process {
$objects += $InputObject
}
END {
$properties = $objects[0].psobject.properties |%{$_.name}
$array.Value = New-Object 'object[,]' ($objects.Count+1),$properties.count
# i = row and j = column
$j = 0
$properties |%{
$array.Value[0,$j] = $_.tostring()
$j++
}
$i = 1
$objects |% {
$item = $_
$j = 0
$properties | % {
if ($item.($_) -eq $null) {
$array.value[$i,$j] = ""
}
else {
$array.value[$i,$j] = $item.($_).tostring()
}
$j++
}
$i++
}
$array
}
}
csvToExcel "storage_stats.csv" ";"
你可以按原样使用上面的代码;它应该将任何CSV转换为Excel。只需将路径更改为CSV和底部的分隔符。
其他回答
警告:Excel '07(至少)有一个(另一个)错误:如果字段的内容中有逗号,它不会正确解析="field, contents",而是将逗号后的所有内容放入下面的字段中,而不管引号是什么。
我发现唯一有效的解决方法是当字段内容包含逗号时消除=。
这可能意味着有些字段不可能在Excel中完全“正确”地表示,但到目前为止,我相信没有人会感到太惊讶。
对于同样的问题,我所做的是在每个csv值之前添加以下内容: “=”“” 在Excel中打开文件之前,在每个CSV值后加上双引号。以以下值为例:
012345,00198475
在Excel中打开之前,这些应该更改为:
"="""012345","="""00198475"
这样做之后,每个单元格值在Excel中都显示为公式,因此不会格式化为数字、日期等。例如,012345的值显示为:
="012345"
SELECT CONCAT('\'',NOW(),'\''), firstname, lastname
FROM your_table
INTO OUTFILE 'export.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\n'
在双引号中添加空格前缀解决了这个问题!!
我在csv文件的一个列中有“7/8”这样的数据,MS-Excel将其转换为“07-Aug”。但是使用“LibreOffice Calc”就没有问题了。
为了解决这个问题,我只是给空格字符加上前缀(在7之前添加空格),比如“7/8”,这对我来说很有效。这是为Excel-2007测试的。
(EXCEL 2016及以后版本,实际上我没有尝试过旧版本)
打开新空白页 转到“数据”标签 点击“来自文本/CSV”,选择CSV文件 检查预览您的数据是否正确。 在сase中,当某些列被转换为日期时,单击“编辑”,然后通过单击列头部的日历选择类型文本 点击“关闭并加载”