我有一个按序列号跟踪小部件销售的数据库。用户输入购买者数据和数量,然后将每个窗口小部件扫描到自定义客户端程序中。然后,他们确定订单。这一切都完美无瑕。

一些客户想要他们购买的小部件的Excel兼容电子表格。我们使用PHP脚本生成此文件,该脚本查询数据库并以CSV格式输出结果以及商店名称和相关数据。

在文本编辑器(如记事本或vi)中打开时,文件如下所示:

"Account Number","Store Name","S1","S2","S3","Widget Type","Date"
"4173","SpeedyCorp","268435459705526269","","268435459705526269","848 Model Widget","2011-01-17"


您会看到,序列号存在(在这种情况下为两次,并非所有辅助序列都相同)并且是一长串数字。
在Excel中打开此文件时,结果变为:

Account Number  Store Name  S1           S2  S3           Widget Type       Date
4173            SpeedyCorp  2.68435E+17      2.68435E+17  848 Model Widget  2011-01-17


您可能已经注意到,序列号用双引号引起来。 Excel似乎不尊重.csv文件中的文本限定符。将这些文件导入Access时,难度为零。以文本形式打开它们时,一点也​​不麻烦。但是Excel一定会将这些文件转换成无用的垃圾。可以说,试图指导最终用户使用非默认应用程序打开CSV文件的技术已经变得很烦人。有希望吗?是否有我找不到的设置? Excel 2003、2007和2010似乎就是这种情况。

评论

我可以给名字加+1吗?

Excel似乎不尊重.csv文件中的文本限定符-双引号不是文本限定符,它们只是在数据中包含逗号,如果您在数据中不使用逗号,则它们是没有意义的。 CSV文件中的所有数据都是无类型的,因此Excel只能猜测您的大序列号是一个数字,也就是说,当您以Excel的15位数字的最大精度运行时,这就是对数字进行截断的原因。
Excel似乎不尊重双引号中的所有逗号。考虑一下“ 2012年8月12日”,Excel也将其转化为垃圾。

我想提到这个SU问题。它说明了在Excel中处理CSV时具有哪些选项。

@nixda谢谢!这些都是有用的建议,尤其对于经验丰富的用户。我的问题几乎更多是人为问题,因为Excel将自身与.csv文件关联,人们看到了该图标,然后双击(因为这是您打开东西的方式),然后通常单击Save(因为我们一直在告诉他们保存!),一切都丢失了。但是我一定会尽可能使用您的方法。

#1 楼


但是Excel一定会将这些文件转换成无用的垃圾。


Excel是无用的垃圾。

解决方案

如果有任何客户想要Excel格式的数据,我会有些惊讶无法将这三列的可见格式更改为零位数的“数字”或“文本”。但是,我们假设没有一个简短的操作文档。

您的选择是:


将非数字字符而不是空格字符插入到您的序列号。
以某种默认格式编写一个xls文件或xlsx文件。
作弊并将这些数字作为公式="268435459705526269","",="268435459705526269"输出(也可以执行="268435459705526269",,="268435459705526269"来节省2个字符)。这样的优点是可以正确显示,并且通常可能有用,但是会被破坏(因为它们是公式)。

注意选项3,因为某些程序(包括Excel和Open Office Calc)将不再将=""字段内的逗号视为转义。这意味着="abc,xyz"将跨越两列并中断导入。

使用"=""abc,xy"""的格式可以解决此问题,但是由于Excel的公式长度限制,此方法仍将您限制为255个字符。

评论


实际上,这并不苛刻。将上面的数字之一复制并粘贴到Excel中,然后根据建议更改数字格式。 Excel更改该值,从而导致垃圾。

– Joe Internet
2011年1月19日,下午2:03

@Tyler-我不认为Excel是垃圾,只是说OP在这种情况下会产生垃圾是正确的。这实际上是一个很好的问题,没有看似优雅的解决方案。

– Joe Internet
2011年1月19日,下午3:50

建议使用“单元格格式...”选项,而我尝试使用它。在这种情况下,打开文件的那一刻,Excel似乎会将序列转换为科学计数法(商定的,不是意外的)并丢掉了精度。当您将它们更改为数字或文本时,字符串不会返回。这确实是问题的实质。输出为公式可能会做到这一点……我没想到。

– atroon
2011年1月19日15:17

@ DMA57361该行为是无法预期的,可以确定。数值精度已得到很好的证明,但excel如何读取CSV却没有。缺乏警告和默默丢弃数据是荒谬的。您甚至无法告诉Excel如何导入数据的事实同样荒谬。需要否定性吗?不,但是诚实是最好的政策,这就是我的感受。

–泰勒
2011年2月3日,下午5:27

这也适用于带有破折号的ID号。如果该值是有效日期,则Excel会将其转换为日期字段。例如,5-1将转换为May-1。添加双引号和一个空格,即“ 5-1”,在Excel中显示为5-1的文本字段。

–山姆·泰森(Sam Tyson)
2012年6月25日17:42

#2 楼

我们有一个类似的问题,即我们的CSV文件的列包含3-5等范围,而Excel总是将其转换为日期,例如3月3日3-5日,然后切换回数字,我们得到了一个无用的日期整数。我们通过


将CSV重命名为TXT扩展名来解决了这个问题。
然后在Excel中打开它后,它将在文本导入向导中启动
在步骤3中向导中的3之多,我们告诉它有问题的列是文本,并且已正确导入。

您可以在此处执行相同的操作。



干杯

评论


+1是正确的做法。 (编辑:对不起,您必须进行一点编辑以阐明解决方案)

–杰伊·威克(Jay Wick)
2012年2月7日在22:41



您不必重命名文件。只需使用导入向导Shift-选择所有列,然后选择作为文本即可。

– nixda
13年1月7日在8:58

文本导入向导就是答案。所有其他解决方案都是不必要的黑客,因为他们不了解如何使用Excel查看和编辑CSV。

– Excellll
2014年10月28日在22:27

@Excellll,确保一次只执行一个文件。在自动执行此过程时,“不必要的黑客”通常可以节省时间。

–Parrish丈夫
15年3月24日在18:07

当标准用户使用excel显示CSV文件时,这是完全没有用的。在我试图向约15个初学技能的办公室用户解释如何使用text-import-wizard之前,我宁愿自己键入excel文档源代码。

–北基多南
15年11月30日在8:21

#3 楼

更好的解决方案是生成XML工作簿。像这样:

<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  </OfficeDocumentSettings>

  <ss:Worksheet ss:Name="Sheet 1">
    <Table>
    <Column ss:Width="100"/>
    <Column ss:Width="100"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="150"/>
    <Column ss:Width="80"/>
    <Column/>

    <Row>
      <Cell><Data ss:Type="String">Account Number</Data></Cell>
      <Cell><Data ss:Type="String">Store Name</Data></Cell>
      <Cell><Data ss:Type="String">S1</Data></Cell>
      <Cell><Data ss:Type="String">S2</Data></Cell>
      <Cell><Data ss:Type="String">S3</Data></Cell>
      <Cell><Data ss:Type="String">Widget Type</Data></Cell>
      <Cell><Data ss:Type="String">Date</Data></Cell>
    </Row>

    <Row>
      <Cell><Data ss:Type="String">4173</Data></Cell>
      <Cell><Data ss:Type="String">SpeedyCorp</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">x</Data></Cell>
      <Cell><Data ss:Type="String">268435459705526269</Data></Cell>
      <Cell><Data ss:Type="String">848 Model Widget</Data></Cell>
      <Cell><Data ss:Type="String">2011-01-17</Data></Cell>
    </Row>


    </Table>
    <x:WorksheetOptions/>
  </ss:Worksheet>
</Workbook>


文件必须具有.xml扩展名。 Excel和OpenOffice可以正确打开它。

评论


您是说OP应该使用PHP脚本将数据库转换为XML格式吗?

– Prasanna
2015年9月30日在7:23

比让用户在Excel中打开.csv或弄乱您的CSV干净得多,这样只有Excel才能理解您的CSV。它甚至没有架构那么复杂。

– Binki
16年5月10日在15:06



该标准在哪里记录?我想了解更多有关可用数据类型的信息。

–约翰·多尔蒂(John Doherty)
17-10-7在11:49

#4 楼

我的解决方案:
导入序列号时遇到相同的问题。
它们不必视为数字,即不对其执行任何数学功能,但我们需要完整的数字在这里。
我最简单的方法是在序列号中插入一个空格。
例如“ 12345678 90123456 1234”。
当Excel导入它时,它将被视为文本而不是数字。

评论


在此解决方案发布前的16个月中,该解决方案已在投票率最高的答案中提出。

– Alex M
20 Mar 16 '20在22:38

#5 楼

导入向导是针对临时用户和一次性情况的最佳解决方案。如果需要编程解决方案,则可以使用QueryTables.Add方法(导入向导在后台使用的方法)。

Workbooks.Add
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & "C:\myfile.csv", Destination:=Range("$A"))
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 437
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = False
    .TextFileSemicolonDelimiter = False
    .TextFileCommaDelimiter = True
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(1, 2, 2) 'Edit this line. Add a number for each column, 1 is general, 2 is text. Search the internet for other formats.
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
End With


#6 楼

我的帐号长了乱码。

这是我的解决方法:

在Libre Office / Open Office中打开file.csv(可能需要指定定界符等),然后将文件另存为Excel XML文件。

然后在Excel中打开此文件,然后您将看到列不再更改为科学格式或其他格式。为了安全起见,右键单击该列,然后将格式明确设置为“文本”,然后另存为Excel文件格式。

打开Excel格式文件,该列仍然应该可以!

评论


尽管这可行,但尝试向只会说英语的人解释为什么他需要使用其他办公套件会导致解决的许多问题。我个人认为,M $ Office的替代软件非常有用,但我意识到我无法转换所有人。

– atroon
13年5月17日在18:31