如何阻止 Excel 吃掉我的美味 CSV 文件并排出无用的数据?

atr*_*oon 133 csv microsoft-excel

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

一些客户想要他们购买的小部件的 Excel 兼容电子表格。我们使用 PHP 脚本生成它,该脚本查询数据库并将结果输出为带有商店名称和相关数据的 CSV。这也非常有效。

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

"Account Number","Store Name","S1","S2","S3","Widget Type","Date"
"4173","SpeedyCorp","268435459705526269","","268435459705526269","848 Model Widget","2011-01-17"
Run Code Online (Sandbox Code Playgroud)

如您所见,序列号存在(在本例中为两次,并非所有二级序列号都相同)并且是一长串数字。在 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
Run Code Online (Sandbox Code Playgroud)

您可能已经观察到,序列号用双引号括起来。Excel 似乎不尊重 .csv 文件中的文本限定符。将这些文件导入 Access 时,我们的难度为零。将它们作为文本打开时,完全没有问题。但是 Excel 毫无疑问会将这些文件转换为无用的垃圾。试图指导最终用户使用非默认应用程序打开 CSV 文件的艺术变得,容我们说,令人厌烦。有希望吗?是否有我找不到的设置?Excel 2003、2007 和 2010 似乎就是这种情况。

Tyl*_*ler 58

但是 Excel 毫无疑问会将这些文件转换为无用的垃圾。

Excel 是无用的垃圾。

解决方案

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

您的选择是:

  1. 将非数字而非空白字符放入您的序列号中。
  2. 用一些默认格式写出一个 xls 文件或 xlsx 文件。
  3. 作弊并将这些数字作为公式输出="268435459705526269","",="268435459705526269"(您也可以为自己="268435459705526269",,="268435459705526269"节省 2 个字符)。这具有正确显示的优点,并且可能通常很有用,但被巧妙地破坏了(因为它们是公式)。

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

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

  • @DMA57361 该行为是不可预料的,它是可确定的。数字精度有据可查,excel 如何读取 CSV 则没有。缺乏警告和默默丢弃数据是荒谬的。你甚至不能告诉 Excel 如何导入数据的事实同样荒谬。消极情绪是否*需要*?不,但诚实是最好的政策,这就是我的感受。 (10认同)
  • 其实这并不苛刻。将上面的数字之一复制并粘贴到 Excel 中,然后按照建议更改数字格式。 Excel 更改值,导致产生垃圾。 (2认同)
  • @Tyler - 我不认为 Excel 是垃圾,只是说 OP 在这种情况下产生垃圾是正确的。这实际上是一个很好的问题,没有看似优雅的解决方案。 (2认同)
  • 已建议使用 Format Cells... 选项,我已尝试使用它。在这种情况下,当您打开文件时,Excel 似乎将序列号转换为科学记数法(同意,并非意外)并提高精度。当您将它们更改为数字或文本时,字符串不会返回。**那**确实是问题的本质。虽然输出为公式可能会这样做......我没有想到这一点。 (2认同)
  • 这也适用于带有破折号的 ID 号。如果该值是有效日期,则 Excel 会将其转换为日期字段。例如,5-1 将转换为 May-1。添加双引号和空格,即“5-1”,在 Excel 中显示为文本字段 5-1。 (2认同)

小智 44

我们有一个类似的问题,我们有包含范围的 CSV 文件,如 3-5 和 Excel 总是将它们转换为日期,例如 3-5 将是 3 月 3 日,之后切换回数字给我们一个无用的日期整数。我们绕过它

  1. 将 CSV 重命名为 TXT 扩展名
  2. 然后当我们在 Excel 中打开它时,这将启动文本导入向导
  3. 在向导的第 3 步(共 3 步)中,我们告诉它有问题的列是文本,并且它们已正确导入。

我认为你可以在这里做同样的事情。

文本导入向导

干杯

  • +1 是正确的做法。*(编辑:抱歉不得不编辑一些以澄清解决方案)* (2认同)
  • 您不必重命名文件。只需使用导入向导 Shift 并选择所有列并选择为文本。 (2认同)
  • 文本导入向导就是答案。由于不了解如何使用 Excel 查看和编辑 CSV,所有其他解决方案都是不必要的黑客。 (2认同)
  • 当标准用户使用 excel 来显示 CSV 文件时,这完全没用。在我尝试向大约 15 位初级办公用户解释如何使用文本导入向导之前,我宁愿自己输入 excel 文档源代码。 (2认同)

小智 9

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

<?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>
Run Code Online (Sandbox Code Playgroud)

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

  • 比让用户在 Excel 中打开 .csv 或弄乱您的 CSV 以便只有 Excel 可以理解您的 CSV 要干净得多。它甚至没有那么复杂的模式。 (2认同)