使用 bash 脚本将多个 excel 文件合并到一个 excel 工作簿但不同的工作表中

Posted

技术标签:

【中文标题】使用 bash 脚本将多个 excel 文件合并到一个 excel 工作簿但不同的工作表中【英文标题】:merge mutliple excel files into one excel workbook but different worksheets using bash scripting 【发布时间】:2020-08-10 23:19:30 【问题描述】:

如何

    > input: file1_1234.xlsx
             file2_1234.xlsx 
             file3_9999.xlsx 
             file4_1245.xlsx
             file5_9999.xlsx 
             file6_1245.xlsx

输出:

**outputfile_1234.xlsx** which contains 
file1_1234.xlsx
file2_1234.xlsx in two different worksheets


**outputfile_9999.xlsx** which contains 
file3_9999.xlsx
file5_9999.xlsx in two different worksheets


**outputfile_1245.xlsx** which contains 
file4_1245.xlsx
file6_1245.xlsx in two different worksheets

【问题讨论】:

您可以分三个步骤完成:a) 使用 LibreOffice headless(即从命令行)使用命令 soffice --headless --convert-to fods *.xlsx*.xslx 文件转换为 *.fods; b) 生成的文件是纯 XML 文件,可以使用 xsltproc 等工具将其合并为一个 FODS 文件; c) 使用上面的命令将生成的 FODS 文件再次转换为 XLSX(参见:a)。 【参考方案1】:

有趣的问题。

我曾经能够使用 xsltproc 将两个 FODS 电子表格(代表平面打开文档电子表格)合并为一个。两个电子表格都很简单且非常相似。我不知道这是否适用于所有类型的电子表格。

因此,首先需要将 XLSX 电子表格转换为 FODS 电子表格,发出:

soffice --headless --convert-to fods file*.xlsx

命令 xsltproc 需要一个样式表作为参数,它是下一个 XSL 程序:

tablemerge.xsl:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
  xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
  xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
  xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
  xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
  xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
  xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
  xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
  xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
  xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
  xmlns:math="http://www.w3.org/1998/Math/MathML"
  xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
  xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
  xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
  xmlns:ooo="http://openoffice.org/2004/office"
  xmlns:ooow="http://openoffice.org/2004/writer"
  xmlns:oooc="http://openoffice.org/2004/calc"
  xmlns:dom="http://www.w3.org/2001/xml-events"
  xmlns:xforms="http://www.w3.org/2002/xforms"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:rpt="http://openoffice.org/2005/report"
  xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:grddl="http://www.w3.org/2003/g/data-view#"
  xmlns:tableooo="http://openoffice.org/2009/table"
  xmlns:drawooo="http://openoffice.org/2010/draw"
  xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
  xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
  xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"
  xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
  xmlns:css3t="http://www.w3.org/TR/css3-text/" 
  office:version="1.2" 
  office:mimetype="application/vnd.oasis.opendocument.spreadsheet">

  <xsl:template match="table:table">
    <!-- copy table:table from main file -->
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
    <table:table 
      table:name="document($secondfile)//table:table/@table:name" 
      table:style-name="document($secondfile)//table:table/@table:style-name">
    <!-- copy table:table from second file -->
      <xsl:copy-of select="document($secondfile)//table:table/child::*" />
    </table:table>
  </xsl:template>

   <!-- default template: identity transform -->
   <xsl:template match="/ | @* | node()">
     <xsl:copy>
       <xsl:apply-templates select="@* | node()" />
     </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

必须按如下方式调用此 XSL 程序:

xsltproc --stringparam secondfile file2.fods tablemerge.xsl file1.fods > mergedtables.fods

现在,将所有这些部分连接在一起的脚本可能是:

脚本:

#!/bin/bash

soffice --headless --convert-to fods file*.xlsx

for key in $(ls file*.xlsx | cut -d . -f 1 | cut -d _ -f 2 | sort -u)
do
  outputfile=outputfile_$key.fods
  inputfiles=( file*_$key.fods )
  maininputfile=$inputfiles[0]
  secondinputfile=$inputfiles[1]

  xsltproc --stringparam secondfile $secondinputfile tablemerge.xsl $maininputfile

  soffice --headless --convert-to xslx outputfile*.fods
done

【讨论】:

以上是关于使用 bash 脚本将多个 excel 文件合并到一个 excel 工作簿但不同的工作表中的主要内容,如果未能解决你的问题,请参考以下文章

循环浏览文件夹以将多个 Excel 工作表合并为一列

如何将多个excel文件合并?

将多个 gprof 结果文件合并到一个文件中

excel多个文件合并一个文件怎么做?

多个EXCEL的CSV文件合并时会把每个文件的表头重复合并到结果文件里,能否让合并结果只有一个表头呢?

linux中怎么将文件合并