最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java實(shí)現(xiàn)解析Excel公式

 更新時(shí)間:2024年02月28日 14:13:10   作者:葡萄城官網(wǎng)  
在日常工作中,我們經(jīng)常需要在Excel中使用公式對(duì)表中數(shù)據(jù)進(jìn)行計(jì)算和分析,所以本文小編主要來和大家介紹一下如何在Java中實(shí)現(xiàn)解析Excel公式,感興趣的可以了解下

前言

在日常工作中,我們經(jīng)常需要在Excel中使用公式對(duì)表中數(shù)據(jù)進(jìn)行計(jì)算(求和、求差和求均值等)和分析,從而實(shí)現(xiàn)對(duì)數(shù)據(jù)的分類,通常情況下,當(dāng)數(shù)據(jù)量較少或場景變化單一的情況下,使用公式可以滿足用戶的要求,但當(dāng)數(shù)據(jù)量較大或者場景變化復(fù)雜的情況下,使用公式也無法滿足用戶的需求的情況。這個(gè)時(shí)候就可以用編碼的方式來解決,以下面的背景需求為例,小編將為大家介紹如何使用葡萄城公司的Java API 組件GrapeCity Documents for Excel (以下簡稱GcExcel)解析Excel中的現(xiàn)有公式并根據(jù)需求對(duì)其進(jìn)行修改。

背景需求

下圖是一張銷售數(shù)據(jù)表,左側(cè)顯示原始銷售數(shù)據(jù),包括銷售代表的姓名、地區(qū)、產(chǎn)品和銷售數(shù)量,右側(cè)顯示了從原始數(shù)據(jù)中提取的特定的銷售代表對(duì)應(yīng)的銷售分析結(jié)果,以及每個(gè)產(chǎn)品區(qū)域組合的月度銷售目標(biāo)進(jìn)度。目標(biāo)進(jìn)度的標(biāo)準(zhǔn)如下:

低于 2500:低于目標(biāo)

超過 3000:達(dá)到目標(biāo)

超過 5000:高于目標(biāo)

一般情況下,我們使用Excel中的 IF、ISNUMBER 和 FILTER 函數(shù)就可以實(shí)現(xiàn)將左側(cè)的銷售原始數(shù)據(jù)轉(zhuǎn)化為右側(cè)的銷售分析結(jié)果,如下所示:

=IF(ISNUMBER(FILTER(A2:D19,A2:A19=“Fritz”)),IFS(FILTER(A2:D19,A2:A19=“Fritz”)>5000,“Above Target”,FILTER(A2:D19,A2:A19=“Fritz”)>3000,“On Target”,FILTER(A2:D19,A2:A19=“Fritz”)<2500,“Below Target”),FILTER(A2:D19,A2:A19=“Fritz”))

但是這樣的話就會(huì)出現(xiàn)一個(gè)問題,對(duì)于不同的人名,小編需要將上面公式中銷售代表的姓名進(jìn)行替換,也就是需要不斷地手動(dòng)改變姓名執(zhí)行操作,這一舉動(dòng)不僅枯燥,而且很容易出錯(cuò)。因此這個(gè)時(shí)候就可以使用GcExcel通過解析公式并使用解析的語法樹輕松替換銷售代表姓名,可以簡化此操作。

使用 Java解析和修改 Excel 公式

首先,創(chuàng)建一個(gè)新的 Java項(xiàng)目,并使用 Maven 包管理器安裝 GcExcel 包,然后按照前面的步驟操作。

1、使用示例數(shù)據(jù)初始化工作簿

實(shí)例化 Workbook 類的實(shí)例并從 Excel 文件導(dǎo)入示例數(shù)據(jù),如下所示。

//Create a new workbook
Workbook workbook = new Workbook();
//Load sample data from excel file
workbook.open("SampleData.xlsx");

2、提取公式

在工作簿加載示例數(shù)據(jù)和預(yù)期公式后,我們從工作表中提取所需的公式,以便使用 Formula 屬性進(jìn)行解析和修改。

GcExcel API 提供的公式解析器希望傳遞的公式不帶“=”(等于)運(yùn)算符,以便成功進(jìn)行公式解析。因此,請(qǐng)注意如何在不使用“=”運(yùn)算符的情況下提取公式。

//Fetch worksheet
IWorksheet worksheet = workbook.getWorksheets().get(0);
//Fetch the original formula which needs to be parsed.
String originalFormula = worksheet.getRange("H3").getFormula().substring(1);

3、解析公式

調(diào)用 FormulaSynatxTree 類的 Parse 方法來解析公式并生成語法樹,幫助您理解公式包含的所有不同類型的值、運(yùn)算符和函數(shù)。

公式語法樹的每個(gè)標(biāo)記都由 GcExcel API 中的其他類表示,例如函數(shù)的 FunctionNode、運(yùn)算符的 OperatorNode 等。

下面的代碼解析了上一步中提取的銷售分析公式。然后,它將生成的 FormulaSyntaxTree 中的值附加到工作簿,該工作簿隨后保存為 Excel 文件,以幫助您了解公式的語法樹。

public static class Tuple {
    String TypeName;
    int IndentLevel;
    String Content;

    Tuple(String TypeName, int IndentLevel, String Content) {
        this.TypeName = TypeName;
        this.IndentLevel = IndentLevel;
        this.Content = Content;
    }
}

public static void flatten(SyntaxNode node, int level, List<Tuple> displayItems) {
    displayItems.add(new Tuple(node.getClass().getSimpleName(), level, node.toString()));
    for (SyntaxNode child : node.getChildren()) {
        flatten(child, level + 1, displayItems);
    }
}

//Method to parse a formula and print the syntax tree
public static void ParseAndPrint(IWorksheet worksheet, String formula)
{
    // Get syntax tree
    FormulaSyntaxTree syntaxTree = FormulaSyntaxTree.Parse(formula);

    // Flatten nodes
    List<Tuple> displayItems = new ArrayList<>();
    flatten(syntaxTree.getRoot(), 0, displayItems);

    // Output
    worksheet.setShowRowOutline(false);
    worksheet.getOutlineColumn().setColumnIndex(1);

    // Header
    worksheet.getRange("A1").setValue("Formula");
    worksheet.getRange("A3").setValue("Syntax node");
    worksheet.getRange("B3").setValue("Part");

    // Values
    worksheet.getRange("B1").setValue("'=" + formula);
    for (int i = 0; i < displayItems.size(); i++)
    {
        Tuple item = displayItems.get(i);
        String text = "'" + item.TypeName;

        worksheet.getRange(i + 4, 0).setValue(text);
        worksheet.getRange(i + 4, 0).setIndentLevel(item.IndentLevel);
        worksheet.getRange(i + 4, 1).setValue("'" + item.Content);
    }

    //Apply styling
    worksheet.getRange("A1:B3").getInterior().setColor(Color.FromArgb(68, 114, 196));
    worksheet.getRange("A1:B3").getFont().setColor(Color.GetWhite());
    worksheet.getRange("A1:B3").getBorders().setColor(Color.FromArgb(91, 155, 213));
    worksheet.getRange("A1:B3").getBorders().setLineStyle(BorderLineStyle.Thin);
    worksheet.getRange("A1,A3,B3").getFont().setSize(14);
    worksheet.getRange("A1,A3,B3").getFont().setBold(true);
    worksheet.getRange("A:C").getEntireColumn().autoFit();
}

下圖是生成的 FormulaSyntaxTree 的效果圖圖。請(qǐng)注意,這只是完整語法樹的一部分:

4、修改公式

從上一步生成的語法樹中,可以看到銷售代表姓名以 TextNode 形式表示,并且在公式中多次出現(xiàn)。我們可以通過簡單的查找和替換操作來替換所有這些出現(xiàn)的情況,如下面的代碼所示:

1.替換公式中的銷售代表姓名,從姓名列表開始。我們使用 UNIQUE 函數(shù)從原始數(shù)據(jù)中過濾掉唯一名稱列表。然后使用這個(gè) UNIQUE 函數(shù)的結(jié)果來解析和修改所有銷售代表的銷售分析公式。

2.使用 TextNode 類修改銷售代表姓名。下面的代碼初始化 TextNode 類的實(shí)例,并將要在公式中搜索的銷售代表姓名作為參數(shù)傳遞。該實(shí)例可以稱為查找節(jié)點(diǎn)。

3.接下來,我們初始化 TextNode 類的另一個(gè)實(shí)例,并將公式中要替換的銷售代表姓名作為參數(shù)傳遞。該實(shí)例可以稱為替換節(jié)點(diǎn)。

4.下面的代碼中定義了一個(gè)遞歸函數(shù) replaceNode,用于遍歷語法樹的所有子節(jié)點(diǎn),并將每個(gè)出現(xiàn)的 Find 節(jié)點(diǎn)替換為 Replace 節(jié)點(diǎn)。每個(gè)銷售代表都會(huì)重復(fù)此操作。

5.修改公式后,新公式將分配給工作表中的單元格以生成預(yù)期的銷售報(bào)告。

下面的代碼包含一些格式化代碼來格式化銷售報(bào)告內(nèi)容。

//Find and replace
public static void replaceNode(SyntaxNode lookIn, SyntaxNode find, SyntaxNode replacement)
{
    List<SyntaxNode> children = lookIn.getChildren();

    for (int i = 0; i < children.size(); i++)
    {
        SyntaxNode child = children.get(i);
        if (child.equals(find))
        {
            children.set(i, replacement);
        }
        else
        {
            replaceNode(child, find, replacement);
        }
    }
}
//Method to parse and modify the formula
public static void ModifyFormula(IWorksheet worksheet, String originalFormula)
{
    //Apply UNIQUE formula to get unique sales representatives list
    worksheet.getRange("F1").setValue("Unique Rep");
    worksheet.getRange("F2").setFormula2("=UNIQUE(A2:A19)");
    IRange uniqueRep = worksheet.getRange("F2#");
    // Apply Styling
    worksheet.getRange("F:F").getEntireColumn().autoFit();
    worksheet.getRange("F1").getInterior().setColor(Color.FromArgb(68, 114, 196));
    worksheet.getRange("F1").getFont().setColor(Color.GetWhite());
    worksheet.getRange("F2#").getBorders().setColor(Color.FromArgb(91, 155, 213));
    worksheet.getRange("F2#").getBorders().setLineStyle(BorderLineStyle.Thin);

    //Get syntax tree
    FormulaSyntaxTree syntaxTree = FormulaSyntaxTree.Parse(originalFormula);

    //Find
    TextNode findText = new TextNode("Fritz");

    //Replacement
    TextNode replaceText = new TextNode("");

    //Loop through names list to modify the formula for each sales representative
    for (int r = 0, resultRow = 3; r < uniqueRep.getCells().getCount(); r++, resultRow = resultRow + 4)
    {
        //Get name to be replaced in the formula
        String cval = uniqueRep.getCells().get(r).getValue().toString();

        if (!Objects.equals(findText.getValue(), cval))
        {
            //Assign name to be replaced to Replace TextNode
            replaceText.setValue(cval);

            //Invoke the recursive method to perform find and replace operation
            replaceNode(syntaxTree.getRoot(), findText, replaceText);

            //Assign the modified formula to a cell in the worksheet
            String resultRange = "H" + resultRow;
            worksheet.getRange(resultRange).setFormula2("=" + syntaxTree.toString());
            worksheet.getRange(resultRange + "#").getBorders().setColor(Color.FromArgb(91, 155, 213));
            worksheet.getRange(resultRange + "#").getBorders().setLineStyle(BorderLineStyle.Thin);

            //Update the value of Find node to perform find and replace operation for next sales representative name
            findText = replaceText;
        }
    }
}

這是修改后的公式之一:

=IF(ISNUMBER(FILTER(A2:D19,A2:A19=“Xi”)),IFS(FILTER(A2:D19,A2:A19=“Xi”)>5000,“Above Target”,FILTER(A2:D19,A2:A19=“Xi”)>3000,“On Target”,FILTER(A2:D19,A2:A19=“Xi”)<2500,“Below Target”),FILTER(A2:D19,A2:A19=“Xi”))

5、保存 Excel 文件

將所有修改的公式添加到工作表后,將調(diào)用 Workbook 類的 Save 方法來保存 Excel 文件,如下面的代碼所示:

//Save modified Excel file
workbook.save("ModifiedFormula.xlsx", SaveFileFormat.Xlsx);

打開保存的 Excel 文件可以看到下圖:

到此這篇關(guān)于使用Java實(shí)現(xiàn)解析Excel公式的文章就介紹到這了,更多相關(guān)Java解析Excel公式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

  • Java中的List接口實(shí)現(xiàn)類LinkList和ArrayList詳解

    Java中的List接口實(shí)現(xiàn)類LinkList和ArrayList詳解

    這篇文章主要介紹了Java中的List接口實(shí)現(xiàn)類LinkList和ArrayList詳解,List接口繼承自Collection接口,是單列集合的一個(gè)重要分支,實(shí)現(xiàn)了List接口的對(duì)象稱為List集合,在List集合中允許出現(xiàn)重復(fù)的元素,所有的元素是以一種線性方式進(jìn)行存儲(chǔ)的,需要的朋友可以參考下
    2024-01-01
  • Springboot?jpa使用sum()函數(shù)返回結(jié)果如何被接收

    Springboot?jpa使用sum()函數(shù)返回結(jié)果如何被接收

    這篇文章主要介紹了Springboot?jpa使用sum()函數(shù)返回結(jié)果如何接收,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Springboot基于BCrypt非對(duì)稱加密字符串的實(shí)現(xiàn)

    Springboot基于BCrypt非對(duì)稱加密字符串的實(shí)現(xiàn)

    本文主要介紹了Springboot基于BCrypt非對(duì)稱加密字符串的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java內(nèi)部類的全限定名規(guī)律代碼示例

    Java內(nèi)部類的全限定名規(guī)律代碼示例

    這篇文章主要介紹了Java內(nèi)部類的全限定名規(guī)律代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)

    Spring Boot攔截器Interceptor與過濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)

    對(duì)比SpringBoot攔截器與過濾器在執(zhí)行順序、作用范圍、異常處理等核心差異,指導(dǎo)開發(fā)實(shí)踐與選型策略,強(qiáng)調(diào)攔截器適合Web層通用邏輯,過濾器用于底層處理,建議結(jié)合APM工具優(yōu)化性能,感興趣的朋友跟隨小編一起看看吧
    2025-06-06
  • Jackson自定義序列化與反序列化注解詳解

    Jackson自定義序列化與反序列化注解詳解

    這篇文章主要介紹了Jackson自定義序列化與反序列化注解詳解,某些場景下,我們使用Jackson對(duì)數(shù)據(jù)進(jìn)行序列化或反序列化的時(shí)候,需要對(duì)某些數(shù)據(jù)進(jìn)行特殊處理,需要的朋友可以參考下
    2023-11-11
  • Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例

    Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例

    這篇文章主要介紹了Spring security密碼加密實(shí)現(xiàn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring & Spring Boot 常用注解整理收藏

    Spring & Spring Boot 常用注解整理收藏

    注解就像代碼里的便利貼,用來告訴 Spring 框架:這個(gè)類/方法/變量有什么特殊用途,本文分步驟給大家介紹Spring & Spring Boot 常用注解整理,感興趣的朋友一起看看吧
    2025-05-05
  • 解決異常處理問題:getReader()?has?already?been?called?for?this

    解決異常處理問題:getReader()?has?already?been?called?for?this

    這篇文章主要介紹了解決異常處理:getReader()?has?already?been?called?for?this問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 最新評(píng)論

    甘孜县| 县级市| 抚州市| 厦门市| 玉环县| 綦江县| 元江| 离岛区| 禹州市| 陆川县| 涟源市| 扎赉特旗| 平凉市| 昌都县| 广灵县| 沧源| 微山县| 安图县| 红原县| 关岭| 阿拉善左旗| 洱源县| 大悟县| 海兴县| 永安市| 社旗县| 荔浦县| 阳江市| 丰县| 锦州市| 黑龙江省| 曲阜市| 石城县| 黄石市| 军事| 安西县| 德令哈市| 宜君县| 绩溪县| 图木舒克市| 承德县|