Excel--圖片-公式-賦值-解決方案

Excel2003–公式重新計算問題

需求描述

有個30M的Excel需要導出,其中一個SHEET叫做s1用來做數據輸入,其他的SHEET引用s1的數據進行操作,涉及到公式的計算。

解決方案

1,其他SHEET的公式不自動計算

在excel下載之前,再重新計算一遍。當時沒有什麼好辦法,甚至想到用VBA來解決。
發現poi自帶的函數

HSSFWorkbook fWorkbook = new HSSFWorkbook(fileInput);
fWorkbook.setForceFormulaRecalculation(true); //強制重新計算

poi版本

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.14</version>
</dependency>
2,圖片處理

Excel中對圖片的簡單理解就是:圖片是矩形的,直接確定對角的兩個座標,就確定了圖片的位置。
圖片一個點的座標由兩部分組成:單元格的位置+某個點在該單元格的相對座標,一共四個數字。也就是說確定一個圖片要8個數字。

HSSFSheet autoPicture = fWorkbook.getSheet("sheet1"); //根據SHEET的名字獲得SHEET
HSSFPatriarch autoPicturePaneContainer = autoPicture.createDrawingPatriarch();
//看名字是創建一個圖片的容器,這樣的只能創建一次。
HSSFClientAnchor pl = 
new HSSFClientAnchor(64, 0, 923, 0, (short) 2, 3, (short) 8, 42); //圖片的
autoPicturePaneContainer.createPicture(pl, fWorkbook.addPicture(getResourcesByteArray(tst), HSSFWorkbook.PICTURE_TYPE_JPEG));

這個東西網上比較多,就不多少說了!
但是這樣做是處理不了問題的,比如多個SHEET有多處引用圖片,每次更改位置都要重新修改代碼,或者做一次初始化。
考慮這樣一個解決方案【證實可用】:
使用Excel本身的功能—-Excel圖片引用!就像單元格值引用一樣。
這裏寫圖片描述

修改SHEET2中A2單元格的內容就可以在圖片控件中看到A2單元格內的圖片,解決Excel處理複雜的問題。

3,單元格賦值

不用考慮直接賦值的問題,就是說直接定位A1賦值。一旦Excel結構發生變化,就需要調整代碼或者配置文件。

現提供一個解決方案:

標記我們要賦值的單元格,確定該單元格後給正確的值。
具體實現:
a.定義一套標記語法,個人覺得EL表達式就不錯。eg.#{name} or #{s.name}
b.從SHEET中篩選出我們標記的單元格。
c.給符合的單元格賦值

注意:

1,遍歷某個單元格時,可能遍歷所有,應該只遍歷有值得單元格

2,獲取單元格的值時,注意單元格的類型

3,篩選時獲得了單元格的值,可以考慮使用正則表達式提取花括號裏面的值

4,賦值的時候可以考慮設置單元格的類型爲文本直接強轉賦值

5,在這裏囉嗦一下,獲得name,可以想一下。
   比如name可以是某個對象的屬性,或者某個map的key

說道這裏推薦大家使用JEXL3
https://commons.apache.org/proper/commons-jexl/

這個東西
使用正則表達式取值,然後賦值

private static final Pattern P_EXPRESSION = Pattern.compile("\\$\\{([^\\}]+)\\}");
private String tryEvaluateValue(String value, JexlContext jc) {

        //value 單元格的值

        if (value == null) {
            return null;
        }
        Matcher m = P_EXPRESSION.matcher(value);//正則篩選
        if (!m.find()) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        do {
            String express = m.group(1);
            JexlExpression e = jexl.createExpression(express);
            Object o = e.evaluate(jc);
            m.appendReplacement(sb, o == null ? "" : String.valueOf(o));
        } while (m.find());
        m.appendTail(sb);
        return sb.toString();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章