【问题标题】:Command line execution of Excel functionsExcel函数的命令行执行
【发布时间】:2015-03-06 19:02:07
【问题描述】:

可以从命令行调用 Excel 函数吗?

我不希望与任何文件进行任何交互。我只想像其他命令行工具一样使用这些功能。它应该只服务于某个一次性目的。

例如,如果有办法做这样的事情,我会喜欢它:

$ excel roman(15)
XV

$ excel randbetween(10,20)
14

当然,并不是所有可用的函数都可以这样运行,但是越多越好。

  1. 是否有任何本地应用程序(在 Linux 或 Windows 上,但最好是跨平台的) 提供这种选项?

  2. 或者我们有什么方法可以操纵 excel 本身来做到这一点 (虽然,根据我搜索过的内容,这似乎不是 可能)?

【问题讨论】:

  • 也许可以使用 LibreOffice(可能是 Python 脚本)。但这是谣言,我不知道详情
  • 如果您的公式如此简单,您可以使用其他语言(Common Lisp、Python、Lua、C++、...)对其进行编码
  • 如果您只想要函数而不是与 excel 文件交互,我还建议您研究 Python 之类的东西。
  • @Trengot,我知道 python,但我希望我能够找到一些具有与 Excel 相同的功能集的工具。我不想听起来好像我认为 python 不如 excel 强大。在我看来,情况恰恰相反。无论如何,这是一个很棒的建议。现在,我正在尝试通过谷歌查找是否可以在命令行中单独运行该函数而无需键入'python -c ...'
  • @BasileStarynkevitch,这就是我认为我最后会做的事情。我很懒,我以为其他人可能已经这样做了……:)

标签: linux windows excel command-line


【解决方案1】:

libformula 可能是一个不错的起点。这是一个概念证明:

$ excel 'TRIM(" abc 123  ")'
abc 123

excel 是这个简单的 shell 脚本:

#!/bin/sh

java -cp /usr/share/java/commons-logging.jar:libformula/demo:libbase/dist/libbase-6.1-SNAPSHOT.jar:libformula/dist/libformula-6.1-SNAPSHOT.jar:/home/cwarden/git/excel/src org.xerus.excel.Excel "$1"

org.xerus.excel.Excel 从 argv 中获取一个字符串并将其作为公式计算:

package org.xerus.excel;

import org.pentaho.reporting.libraries.formula.EvaluationException;
import org.pentaho.reporting.libraries.formula.Formula;
import org.pentaho.reporting.libraries.formula.DefaultFormulaContext;
import org.pentaho.reporting.libraries.formula.parser.ParseException;

public class Excel {
        public static void main(final String[] args) throws ParseException, EvaluationException {
                final Formula f = new Formula(args[0]);
                f.initialize(new DefaultFormulaContext());
                final Object o = f.evaluate();
                System.out.println(o);
        }
}

libformula 包含一个演示程序org.pentaho.reporting.libraries.formula.demo.PrintAllFunctions,它会打印出所有支持的函数:

Category User-Defined
ARRAYCONCATENATE, ARRAYCONTAINS, ARRAYLEFT, ARRAYMID, CSVARRAY, CSVTEXT, NORMALIZEARRAY, NULL, PARSEDATE, SEQUENCEQUOTER
Category Information
CHOOSE, COUNT, COUNTA, COUNTBLANK, ERROR, HASCHANGED, INDEX, ISBLANK, ISERR, ISERROR, ISEVEN, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISODD, ISREF, ISTEXT, LOOKUP, NA, VALUE
Category Rounding
INT
Category Mathematical
ABS, ACOS, ACOSH, ASIN, ATAN, ATAN2, AVERAGE, AVERAGEA, COS, EVEN, EXP, LN, LOG10, MAX, MAXA, MIN, MINA, MOD, N, ODD, PI, POWER, SIN, SQRT, SUM, SUMA, VAR
Category Text
ARRAYRIGHT, ASC, CHAR, CLEAN, CODE, CONCATENATE, EXACT, FIND, FIXED, FIXED, LEFT, LEN, LOWER, MESSAGE, MID, PROPER, REPLACE, REPT, RIGHT, SEARCH, STRINGCOUNT, SUBSTITUTE, T, TEXT, TRIM, UNICHAR, UNICODE, UPPER, URLENCODE
Category Date/Time
DATE, DATEDIF, DATETIMEVALUE, DATEVALUE, DAY, DAYS, HOUR, MINUTE, MONTH, MONTHEND, NOW, PREVWEEKDAY, SECOND, TIME, TIMEVALUE, TODAY, WEEKDAY, YEAR, YESTERDAY
Category Logical
AND, FALSE, IF, IFNA, NOT, OR, TRUE, XOR
Category Database
BEGINSWITH, CONTAINS, ENDSWITH, EQUALS, IN, LIKE

【讨论】:

  • 谢谢。这听起来正是我想要的。
【解决方案2】:

这可以在 Java 中使用 Apache POI 用于 Microsoft 文档的 Java API 来完成。在内存中创建 Excel 工作表,从命令行读取公式,然后打印结果。

下面的程序会这样做:

package stackoverflow.excel.formula;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class Main {

    public static void main(String[] args) {
        String formula = args[0];

        // Create a cell and load the formula.
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet();
        Row row = sheet.createRow(0);
        Cell cell = row.createCell(0);
        cell.setCellFormula(formula);

        // Evaluate the formula.
        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
        CellValue cellValue = evaluator.evaluate(cell);
        switch (cellValue.getCellType()) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println(cellValue.getBooleanValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println(cellValue.getNumberValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println(cellValue.getStringValue());
            break;
        default: 
            break;
        }
    }

}

简单的 Maven pom.xml 来构建和打包程序:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>stackoverflow</groupId>
  <artifactId>excel_formula_cli</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <description>https://stackoverflow.com/questions/27843945/command-line-execution-of-excel-functions</description>

  <dependencies>
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml</artifactId>
          <version>3.9</version>
      </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.2</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>stackoverflow.excel.formula.Main</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>


</project>

示例用法:

使用mvn clean package 构建代码并使用java -jar target/excel_formula_cli-0.0.1-SNAPSHOT.jar "YOUR FORMULA HERE" 执行

这样做的缺点是并非所有 Excel 函数都受支持。例如没有实现 ROMAN() 函数。

java -jar target/excel_formula_cli-0.0.1-SNAPSHOT.jar "6*7" => 42.0

java -jar target/excel_formula_cli-0.0.1-SNAPSHOT.jar "roman(15)" => org.apache.poi.ss.formula.eval.NotImplementedException: ROMAN

java -jar target/excel_formula_cli-0.0.1-SNAPSHOT.jar "randbetween(10,20)" => 19.0

如果您对 Apache POI 公式支持的限制感到满意,这将提供一个可移植的跨平台解决方案。请参阅Developing Formula Evaluation - Appendix A 了解支持的功能列表。

【讨论】:

    【解决方案3】:

    一种方法是编写一个脚本(VBScript 或其他脚本环境)来:

    1. 打开一个 Excel 实例(不可见)
    2. 将您的字符串附加到 "=" 符号
    3. 将公式存入单元格
    4. 计算工作表
    5. 向用户显示结果
    6. 关闭 Excel 实例

      这需要安装 Excel 或可以访问 OneDrive。

    【讨论】:

    • 你能用一个例子来编辑你的答案吗?我对 VBScript 一点也不熟悉。但我猜它与 VBA 或 VB 并没有太大区别。
    猜你喜欢
    • 2017-11-30
    • 2015-12-25
    • 2017-05-19
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多