将特定的Excel工作表另存为.csv文件

3

我正在尝试通过Linux命令行将特定的Excel表格保存为CSV格式。 我可以使用以下命令保存第一个工作表:

libreoffice --headless --convert-to csv --outdir /tmp /tmp/test.xls

看起来应该有一种方法可以指定要保存的工作表,但我找不到这个选项。

是否可以通过LibreOffice来保存?


嗨,安德烈。由于我误读了你最初的问题,所以稍作更改。希望这可以帮到你。 - user1123335
3个回答

4

我知道这篇文章的作者可能已经离开了,但既然这是我在搜索中找到的第一个结果,我想我可以试着留下一个可行且实用的答案,供下一个搜寻者使用。

首先,LibreOffice仍然只能保存第一个工作表。如果只需要第一个工作表,那么尝试使用libreoffice --convert-to csv Test.ods命令。有趣的是,GUI也会做同样的事情-只允许你导出活动工作表。所以不是忽略了终端,而是这是LibreOffice的限制。

我需要将几个工作表提取为单独的csv文件,因此“仅活动工作表”对我来说无法胜任。在看到这个答案只提供了宏作为建议后,我继续寻找其他方法。在这个页面之后,我在各个地方都找到了一些获取其他工作表的方法。我不记得有哪些方法允许你提取特定的工作表(除非是我跳过的某个随机的github工具)。

我喜欢使用Gnumeric电子表格应用程序的方法,因为它在大多数中央存储库中,并且不需要先转换为xsl / xslx。但是,有一些需要注意的地方。

首先,如果你想能够提取仅一个工作表而不事先知道工作表名称,则这种方法不适用。如果您事先知道工作表名称或可以接受提取所有工作表,则这个方法效果还不错。工作表名称可以用于创建输出文件,这也很好。

其次,如果你想要引号样式与手动从LibreOffice GUI导出时匹配相同的样式,则需要忘记术语"csv",并考虑使用"txt"来完成转换(例如,将其转换为.txt文件,然后重命名)。否则,如果您不关心引号样式的精确匹配,则这没关系。我将展示两种方法。如果你不知道什么是引号样式,在csv中,如果你有空格或包含,的字符串,你会在单元格值周围加上引号,以区分用于分隔文本的逗号。有些程序会引用所有内容,其他程序只在值中存在空格和/或逗号时才引用,并且其他程序不引用任何内容(或仅在逗号处引用?)。

最后,在通过LibreOffice和Gnumeric的ssconvert工具进行转换时,精度似乎存在差异。对于大多数人和大多数用例来说,这并不重要。但仍然值得注意。在我的原始ods文件中,我有一个公式,它取三个单元格的平均值,分别为58.1459.159.05。当我通过LibreOffice GUI导出时,这个平均值为58.7633333333333。使用ssconvert相同的值为58.76333333333333(即相对于LibreOffice版本多了一位小数)。对于我的目的,我并不真的在意,但是如果您需要与LibreOffice完全匹配或者不想要额外的精度,那么可能会有所影响。
man ssconvert可以看到以下选项:
  • -S,--export-file-per-sheet: 如果导出器一次只支持一个工作表,则为每个表导出一个文件。输出文件名被视为模板,其中工作表号用%n代替,工作表名称用%s代替,在图形导出的情况下,工作表对象名称用%o代替。如果没有替换,则添加默认值".%n"

  • -O, --export-options=optionsstring:指定选择的导出器的参数。 optionsstring是一组用空格分隔的parameter=value对。允许使用的参数名称和值是特定于导出器的,并在下面文档中说明。可以指定多个参数。

在我的测试过程中,如果我用.csv扩展名指定输出文件,则会忽略-O选项。但如果我用.txt,它们就可以正常工作。 我没有涵盖所有选项,并且进行了改述,请参阅man页面以获取更多细节。但您可以在optionsstring中提供以下一些选项:
  • sheet: 工作表的名称。您可以为多个工作表重复使用此选项。在我的测试中,使用索引无效。

  • separator: 如果您想要一个真正的以逗号分隔的值文件,则需要使用逗号。

  • format: 我将使用raw,因为我想要未格式化的值。如果您需要特殊的日期格式等,请阅读手册。

  • quoting-mode: 何时引用值。可以是alwaysautonever。如果您希望尽可能地模仿LibreOffice,请选择never

所以让我们进入终端。

# install gnomic on fedora
$ sudo dnf install -y gnumeric
 
# install gnomic on ubuntu/mint/debian
$ sudo apt-get install -y gnumeric

# use the ssconvert util from gnumeric to do the conversion
# let it do the default quoting - this will NOT match LibreOffice
# in this example, I am just exporting 1 named sheet using
#   -S, --export-file-per-sheet
$ ssconvert -S -O 'sheet=mysheet2' Test.ods test_a_%s.csv
$ ls *.csv
  test_a_mysheet2.csv
 
# same thing but more closely mimicking LibreOffice output
$ ssconvert -S -O 'sheet=mysheet2 separator=, format=raw quoting-mode=never' Test.ods test_b_%s.txt;
$ mv test_b_mysheet2.txt test_b_mysheet2.csv;

# Q: But what if I don't know the sheet names?
# A: then you'll need to export everything
# notice the 'sheet' option is removed from the
# list of -O options vs previous command
$ ssconvert -S -O 'separator=, format=raw quoting-mode=never' Test.ods test_c_%n_%s.txt;
$ ls test_c*
  test_c_0_mysheet.txt    test_c_3_yoursheet2.txt
  test_c_1_mysheet2.txt   test_c_4_yoresheet.txt
  test_c_2_yoursheet.txt  test_c_5_holysheet.txt
  
# Now to rename all those *.txt files to *.csv
$ prename 's/\.txt/\.csv/g' test_c_*.txt
$ ls test_c*
  test_c_0_mysheet.csv    test_c_3_yoursheet2.csv
  test_c_1_mysheet2.csv   test_c_4_yoresheet.csv
  test_c_2_yoursheet.csv  test_c_5_holysheet.csv
  

这个答案解决了我的问题。谢谢。 - Prasanta Bandyopadhyay

0

命令:

soffice --headless "macro:///Library1.Module1.ConvertSheet(~/Desktop/Software/OpenOffice/examples/input/Test1.ods, Sheet2)"

代码:

Sub ConvertSheet( SpreadSheetPath as String, SheetNameSeek as String)
REM IN SpreadSheetPath is the FULL PATH and file
REM IN SheetName sheet name to be found and converted to CSV

Dim Doc As Object  
Dim Dummy()

SheetNameSeek=trim(SheetNameSeek)

If (Not GlobalScope.BasicLibraries.isLibraryLoaded("Tools")) Then
  GlobalScope.BasicLibraries.LoadLibrary("Tools")
End If

REM content of an opened window can be replaced with the help of the frame parameter and SearchFlags:

SearchFlags = com.sun.star.frame.FrameSearchFlag.CREATE + _
com.sun.star.frame.FrameSearchFlag.ALL

REM Set up a propval object to store the filter properties
Dim Propval(1) as New com.sun.star.beans.PropertyValue
Propval(0).Name = "FilterName"
Propval(0).Value = "Text - txt - csv (StarCalc)"
Propval(1).Name = "FilterOptions"
Propval(1).Value = "44,34,76,1"

Url=ConvertToUrl(SpreadSheetPath)

  Doc = StarDesktop.loadComponentFromURL(Url, "MyFrame", _SearchFlags, Dummy)
  FileN=FileNameoutofPath(Url)

  BaseFilename = Tools.Strings.GetFileNameWithoutExtension(FileN)

  DirLoc=DirectoryNameoutofPath(ConvertFromUrl(Url),"/")+"/"

  Sheets = Doc.Sheets

  NumSheets = Sheets.Count - 1
    For J = 0 to NumSheets

        SheetName = Sheets(J).Name

        if (SheetName = SheetNameSeek)  then

          Doc.getCurrentController.setActiveSheet(Sheets(J))        

          Filename = DirLoc + BaseFilename + "."+ SheetName + ".csv"

          FileURL = convertToURL(Filename)

          Doc.StoreAsURL(FileURL, Propval())             
    end if
    Next J
Doc.close(true)
NextFile = Dir
End Sub

感谢您的回复。该脚本将在生产服务器上运行。我需要检查一下是否能够在Libreoffice中添加宏。 - Andrey
宏不是一个选项。我无法相信即使在发布Libreoffice的6版本之后他们仍然不支持保存特定标签页。 - Andrey

0

我最终使用了xlsx2csv。版本0.7.8相当好地支持通用xlsx文件。它允许按编号和名称指定选项卡。

它在宏和复杂的多表文档上表现不佳,但在常规的多表xlsx文档上表现非常出色。

不幸的是,xlsx2csv不支持受密码保护的xlsx文件,因此对于这种情况,我仍然需要使用Win32::OLE Perl模块并在Windows环境下运行它。

从我所看到的,Libreoffice仍然没有通过命令行选择选项卡的能力。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接