Total Pageviews

2016/12/07

[Apache POI] java.lang.IllegalArgumentException: The maximum length of cell contents (text) is 32,767 characters

Problem
I am using Apache POI to write data into Microsoft Excel, but it throw this exception during the process:
java.lang.IllegalArgumentException: The maximum length of cell contents (text) is 32,767 characters


Here is the code snippet, this exception result from line 12:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
                                          List<ColumnIndex> customFieldDefinitions) {
        Cell cell = row.createCell(0);
        cell.setCellValue(issue.getId()); // 編號
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue(issue.getSubject()); // 主旨
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue(issue.getDescription()); // 敘述
        cell.setCellStyle(style);

    }



Solution
According to Apache POI's source code, it will check the maximum length of each cell cannot be larger than 32,767 characters.
https://github.com/apache/poi/blob/31f2b5fdd10c7442576cbed5d37507cb2cdf11cc/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java#L574-L576    


And it is also XLS's imitation, so we need to do substring or use XLSX format instead. We choose the former option. Therefore, my source code should be modified as following:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
                                          List<ColumnIndex> customFieldDefinitions) {
        Cell cell = row.createCell(0);
        cell.setCellValue(issue.getId()); // 編號
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue(issue.getSubject()); // 主旨
        cell.setCellStyle(style);

        // substring 的原因是要避開 The maximum length of cell contents (text) is 32,767 characters
        cell = row.createCell(2);
        cell.setCellValue(StringUtils.substring(issue.getDescription(), 0, 32767)); // 敘述
        cell.setCellStyle(style);

    }


Reference
[1] https://support.office.com/en-us/article/Excel-specifications-and-limits-16c69c74-3d6a-4aaf-ba35-e6eb276e8eaa?CorrelationId=c8dcbafe-51ff-447e-bd62-3c1ce0e1d05e&ui=en-US&rs=en-US&ad=US&ocmsassetID=HP010073849

2016/12/06

[Chrome Extension] Use the chrome.storage API to store, retrieve, and track changes to user data

Requirement
I would like to store user data for my chrome extension, I can use either storage.sync or storage.local. 
When using storage.sync, the stored data will automatically be synced to any Chrome browser that the user is logged into, provided the user has sync enabled.

In the following example, I will utilize storage.sync to fulfill this requirement


How-To
Steps are as bellows:
1. Add options_page and storage permissions in manifest.json 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
  "manifest_version": 2,
  "name": "Build Chrome Extension With AngularJS",
  "description": "利用 AngularJS 建置 Chrome Extension ",
  "version": "1.0",
  "permissions": [ "activeTab", "storage"],
  "browser_action": {
    "default_icon": "img/icon.png",
    "default_popup": "todo.html",
    "default_title": "Build Chrome Extension With AngularJS"
  },
   "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Alt+Shift+D"
      }
    }
  },
  "options_page": "options.html"
}


2. Add options.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
    <title>設定初始工作</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="js/angular.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
    <script src="js/options.js"></script>
</head>

<body>
    <div ng-app="optionsApp" ng-controller="optionController" class="container" >
        <div class="row">
            <label>inital task:</label>
            <input id="initialTask" name="initialTask" ng-model='initialTask' autofocus="true">
            <button id="save" class="btn btn-primary btn-md" ng-click="addInitialTask()">
                <i class="glyphicon glyphicon-pencil"></i>
            </button>
        </div>        
    </div>

</body>
</html>


3. Add options.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
angular.module('optionsApp', [])
    .controller('optionController', function($scope) {
      
      $scope.initialTask = '';

      $scope.addInitialTask = function () {
        var initialTask = $scope.initialTask;
        // Save data using the Chrome extension storage API.
        chrome.storage.sync.set({
          'initialTask' : initialTask
        }, 
        function () {
          alert("設定成功!");
        });
      }
});

function init(){
  // Get data using the Chrome extension storage API.
  chrome.storage.sync.get(
      'initialTask'
  , function(data) {
    document.getElementById('initialTask').value = data.initialTask;   
  });
}

// call init function as page loaded
document.addEventListener('DOMContentLoaded', init);


4. Reload extension and do test


Reference
[1] https://developer.chrome.com/extensions/storage

2016/12/05

[Chrome Extension] Create a simple chrome extenstion with AngularJS 1.X

The steps are as bellows:

1. Download AngularJS 1 from https://angularjs.org/

2. Download Bootstrap from https://getbootstrap.com/

3. Create manifest.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "manifest_version": 2,
  "name": "Build Chrome Extension With AngularJS",
  "description": "利用 AngularJS 建置 Chrome Extension ",
  "version": "1.0",
  "permissions": [ "activeTab" ],
  "browser_action": {
    "default_icon": "img/icon.png",
    "default_popup": "todo.html",
    "default_title": "Build Chrome Extension With AngularJS"
  }
}

4. Create popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html style="min-width:220px;">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Todo list Page</title>
        <script src="js/angular.min.js"></script>
        <script src="js/todo.js"></script>
        <script src="js/bootstrap.min.js"></script>
        <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
    </head>

    <body>
        <div ng-app="todoApp" ng-controller="todoController" class="container">
            <form id='myForm'>
                <div class="row">
                    <input type="text" ng-model="task">
                    <button class="btn btn-primary btn-xs" ng-click="addTask()">
                        <i class="glyphicon glyphicon-plus"></i>
                    </button>
                </div>               
            </form>

            <div class="row">
                <ul>
                    <li ng-repeat="t in tasks track by $index">{{ t }} 
                        <button class="btn btn-default btn-xs" ng-click="deleteTask()">
                            <i class="glyphicon glyphicon-minus"></i>
                        </button>
                    </li>
                </ul>
            </div>
            
        </div>
    </body>
</html>


5. Create a JS file for popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
angular.module('todoApp', [])
    .controller('todoController', function($scope) {

        $scope.tasks = [];
        
        $scope.addTask = function() {
            if(isNotEmptyOrUndefined($scope.task)){
                 $scope.tasks.push($scope.task);
                $scope.task = '';
            } else {
                alert('task name cannot be null');
            }           
        }
        
        $scope.deleteTask = function() {
            $scope.tasks.splice(this.$index, 1);
        }

});

// 檢查是串是否不為空值且不為undefined
function isNotEmptyOrUndefined(str) {
    return str != '' && !angular.isUndefined(str) && str != null;
}


6. Install to Chrome and do test


Source code: https://github.com/junyuo/ChromeExtensions/tree/master/ChromeExtensionWithAngular

2016/12/04

[Chrome Extension] Create a simple chrome extenstion to search picture in Flicker

Steps are as bellows:

1. Create manifest.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "manifest_version": 2,
  "name": "搜尋Flicker照片",
  "description": "Flicker Search Extension",
  "version": "1.0",
  "permissions": [ "activeTab" ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "helloworld.html",
    "default_title": "搜尋Flicker照片"
  }
}


2. Get icons
icon for chrome extension: https://goo.gl/7x1ID8
icon for pupup window: https://goo.gl/YldO4J


3. Create pop up window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html style="min-width:210px;">
    <head>
        <meta charset="UTF-8">
        <title>Hello Page</title>
        <script src="helloWorld.js"></script>
    </head>

    <body>
        <form id='myForm'>
            <img src="magnifier.png" height="20" width="20">
            <input type="text" id="queryString" style="width:100px">
            <button type="submit" id="doSearch">Search</button>
        </form>
    </body>
</html>


4. Create a JS file for popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* The DOMContentLoaded event is fired when the initial HTML document 
 * has been completely loaded and parsed, without waiting for stylesheets, 
 * images, and subframes to finish loading.
 */
document.addEventListener('DOMContentLoaded', function() {

    var searchBtn = document.getElementById('doSearch'); 

    // Execute the following steps as user click Search button       
    searchBtn.addEventListener('click', function(){      
        // Gets query string 
        var queryString = document.getElementById('queryString').value;

        // Create URL with query string
        var newUrl = 'https://www.flickr.com/search/?q='+queryString;

        // Creates a new tab.
        chrome.tabs.create({ url : newUrl});
    }, false);

}, false);   


5. Install to Chrome and do Test


Source code: https://goo.gl/sSRCz0

2016/12/03

[Git] fatal: LF would be replaced by CRLF

Problem
As I try to use the git add command adds a change in the working directory to the staging area. 

It show the fatal error message as bellows:
albert@albert-PC MINGW64 /d/git/ChromeExtensions (master)
$ git add --all
fatal: LF would be replaced by CRLF in HelloWorld/manifest.json



How-to
This fatal error message results from this command fail to pass crlf check.

Here has the solution to fix this file's crlf problem.
If you have Notepad++ installed in your computer, simply follow these steps.
[1] Open the file that is having the fatal issue.
[2] Click Edit -> EOL Conversion, then select Windows Format and save it.





2016/12/02

[閱讀筆記] The Unwritten Laws of Business (2/2)


  1. 有些人似乎永遠都會把水弄的更濁,或無法見樹又見林。能夠從看似複雜的情境裡,分析出最基本、最關鍵的要素,是一種智慧,而且通常必須從經驗累積而成。在這個能力上的差異,會使兩個在各方面都旗鼓相當的人分出高下
  2. 大多數危機在一開始看似很糟糕,但其實根本沒有這麼嚴重,所以要格外謹慎,不要把不好的情勢給誇大了
  3. 任何會議的重點,都在於面對問題和解決問題。人往往會有規避問題的傾向,不是會延遲行動,就是希望事情會自己自動解決。要是在散會前,與會者尚未明確了解工作任務的內容、負責人及時間表,這就是一場失敗的會議
  4. 養成決策明快俐落的習慣,有些主管甚至在決定非常小的問題上,都非常痛苦掙扎,主要是因為他們從來沒有克服對於犯錯的恐懼
  5. 不要讓犯錯的危險,把你的進取新壓抑到「無所冒險,無所得」的程度。預期自己有可能會犯錯,偶而冒一些風險,並且在失敗時承擔苦果是比較健康的。很少錯誤是找不出益處的,就算只有累積了經驗,也算是一種收獲
  6. 以下是執行專案的準則,也可以說是 SOP:
    1. 界定專案目標
    2. 規劃工作
      1. 列出帶完成的每一個步驟
      2. 界定所需的資源,包含人力、資金和設備
      3. 備妥明確的時間表
    3. 執行計畫
    4. 監督進度,並在偏離進度時做出回應
      1. 留意「瓶頸」、「進度停滯」及「中斷的環節」:挹注額外的時間、資金和人力,以追趕落後的工作項目
      2. 如果有必要,修正你的時間表
    5. 盡全力準時完成專案
  7. 過度專注追求安全感,很容易導致更大的危險。身處競爭激烈的世界,你必須冒點風險,放手一搏,因為你不這麼做,其他人也會去做,而他們通常是最後的贏家,他們會讓你為了趕上他們而跑的上氣不接下氣
  8. 積極大膽的計畫原本就會有風險,為了將風險降到最低,在實際可行的前提下,提供替代方案,或是確保有後路可退,避免徹底失敗
  9. 當員工根本不知道自己的工作內容,也不清楚該負責什麼任務時,將嚴重損及士氣和效率。如果指派的任務不明確,很容易就會產生沒完沒了的爭執、混淆和不好的感覺
  10.   如果你對於部屬的工作表現不滿意,應該在一發現這樣的情況時,就立即與他們展開會談,這是你責無旁貸的事情,但是,要做到這點通常不太容易,這需要許多圓融的智慧,以免使部屬感到受挫或被冒犯
  11. 如果你必須開除某個部屬,你必須回答兩個尖銳的問題:『為什麼你要花五年的時間,才發現我能力不足?』以及『你為什麼沒給過我公平的機會,去修正這些缺失?』切記,當你以能力不足開除某人時,不只是該名員工表現差勁,也表示你個人督導不周
  12. 成功的主管會清楚地說明它們對於部屬的要求、目標和期望,之後再予以督導,提供支援
  13. 主管自然而然地想直接行使他們的管理權限,以前迅速明快地解決事情,卻因此沒能顧慮到已經被指派該項工作的人,此舉會嚴重打擊該名部屬的工作士氣
  14. 在對部屬職責的各種粗糙對待中,僅次於職責未被賦予權限的,就是位能讓部屬獲得充分資訊。當員工被指派負責某項專案,如果他們對於專案的過往歷史、現況或未來,都尚未取得足夠的資訊之際,就要求他們展現出可信度,是非常不公平的
  15. 薪資的調整,無論是透過什麼形式,都是對於工作表現優異、承擔更大職責或是為公司增加價值,最恰當的獎勵或報酬
  16. 信心、團隊和人際溝通、工作動力、成就感、適應能力、領導潛力、求知慾、誠信和情緒控制這些技能和特質,才是區分稱職員工與卓越員工的決定條件
  17. 能與各式各樣人相處的能力,是最珍貴的人格特質之一
  18. 與人為善的具體原則
    1. 學會欣賞每個人的優點,而非挑剔他人的缺點
    2. 不要因為受到挑釁,就失去耐心和惱怒
    3. 因為真誠的意見分歧而發生爭論之後,千萬不要心懷怨恨
    4. 養成體貼他人感覺和利益的習慣
    5. 不要太過專注於自己的私利
    6. 養成一有機會就協助他人的習慣
    7. 格外留意,無論在任何場合都要公正無私
    8. 不要對自己太嚴苛,或是太嚴肅看待工作
    9. 多費一點心思,真誠地與人打招呼
    10. 如果你對於別人的動機有所懷疑,先假定他們是無辜的,尤其是當你能夠這麼做的時候
  19. 留心避免和他人爭吵,可是萬一爭端已起,就應該讓對方知道你不是可以輕侮的
  20. 太過刻意地要與每個人和睦相處,因而一味地討人喜歡、甚至是屈服順從,當然是錯誤的作法,遲早有人會利用你這點
  21. 將個人誠信視為你最重要的資產之一,如果你擁有高度的個人誠信,你就會誠實、有品德、值得信賴、負責而且真誠。不妥協和堅守誠信,必然會得到珍貴的報償:信心,亦即同事、部屬和外人對你的信心
  22. 不要低估專業職責和個人責任的範圍,遵循以下幾個簡單的指導原則:
    1. 以有系統的方式處理你所有的工作,尤其是在開發新產品、流程或設備的時候
    2. 找出所需的專業知識和技能,並將之應用到所有活動上
    3. 確實了解合適的規範與標準,並加以採用
    4. 盡可能採行既有的程序
    5. 記錄你自己和部門的活動
  23. 留意你的個人儀表對其他人所造成的影響,還有反過來對你自己的影響
  24. 你必須設法趕上自己領域的最新科技,因為如果你等待別人給你機會,就等於是等著自己被淘汰

2016/12/01

[閱讀筆記] Security Analysis (Part 6)


  1. Balance Sheet 是一家公司在特定時間的資產與負債的snapshot
  2. 當一家公司的資產價值超過獲利能力,代表管理階層未妥善利用公司資產;當一家公司的獲利能力超過資產價值,公司就必須採取一些手段,維護競爭優勢;若公司的資產價值與獲利能力差不多,代表公司對資產有做合理的管理與沒有甚麼特殊措施避免競爭
  3. 投資人應該對於想要買的股票進行 assets valuation,這樣才能對於該公司能夠有完整的picture,投資人也比較有自信能夠抓出適當的 margin of safety
  4. Asset Valuation 包含了主觀與客觀的衡量方式,如在財務報表中無法呈現公司品牌的價值,這部分就屬於主觀;淨利則是透過公司的收入減去支出所得到的數字,則是屬於客觀。其方法包括收益現值法、重置成本法、現行市價法以及清算價格法等等
  5. 研究balance sheet你可以得知:企業花多少資金投資;公司的財務狀況(也就是營運資金)吃緊與否;資本結構的詳細資訊;驗證營收報告的有效性;分析公司收入來源
  6. Book value (帳面價值)是公司之會計紀錄上所記資產的價值,它通常指資產的取得成本減去累積折舊的餘額,並非現金流量,使用不同的折舊方法會有不同的帳面價值。帳面價值只包含形資產,不包含無形資產。實務上,book value 的重要性逐漸式微
  7. 帳面價值的缺憾是無法測量公司的創意與革新 (因為此部分屬於無形資產)。帳面價值最管用的是分析那些有龐大且有形的資產的公司,如鋼鐵業者
  8. 債券票面價值是指債券票面所列價值,即發行人在到期日必須支付的金額。股票票面價值是指公司發行的股票票面上所載明的金額。當發行價格<票面價值,為折價發行(under par);發行價格>票面價值,為溢價發行(over par);當發行價格=票面價值時,是平價發行(at par)
  9. current assets (流動資產) 是指現金或銀行存款、短期投資、應收帳款、應收票據、存貨、預付費用等,具有高度流動性的皆屬於current assets;大樓、設備、不動產等則屬於 fixed assets (固定資產) 。相較於有形資產(只需花錢投資設備),若是靠無形資產所創造出來的營收,受到競爭者的威脅會比較低
  10. 股票的流動資產的價值,其遠比book value 重要。其可作為清算價值的約略的指標。當一家公司價格低於清算價值時,本質上是不合邏輯的,其可能是市場判斷、公司管理的政策或股東對公司資產的態度等等所造成
  11. 清算價值(Liquidation Value)是指公司撤銷或解散時,資產經過清算後,每一股份所代表的實際價值。在理論上,清算價值等於清算時的帳面價值,但由於公司的大多數資產只以低價售出,再扣除清算費用後,清算價值往往小於帳面價值
  12. 當一家公司的股價低於其清算價值(liquidation value)時,不是價格太低,就是公司應該要被清理。對於股民來說,要判斷是不是一個購買點(若該公司可以永續經營勝過破產);對於公司來說,代表著公司錯誤的政策所導致,經營者應該進行矯正措施
  13. 若此檔股票的價格低於清算價值、很清楚沒有浪費公司資產且從過往記錄可以顯示強大的營收能力時,若於此時買進將會是划算的交易,可藉此擴大margin of safety,降低本金損失的風險
  14. 清算價值(Liquidation Value)的重要性不高,因為一般公司並沒有清算的打算。儘管公司的清算價值低於股價,仍不建議買進的原因是:(1) 公司的獲利差強人意;(2) 公司並沒有進行清算的打算
  15. 挑選股票只是一個單一的動作,但是擁有股票則是一個持續的過程
  16. 選股的藝術在於選擇管理良好的企業,濾掉管理不良的企業 。許多企業的管理者都是不稱職且沒有效率的
  17. 公司的股價取決營收然而清算的價值取決所擁有的資產
  18. 低股價的原因通常在於營收衰退與不規則的股利政策
  19. 股票的賣出是根據其營收與股利政策,不是其現金資產價值,除非這些現金資產在未來很有展望
  20. 謹慎的投資人會從資產負債表中,分析公司手上現金是否充裕、流動資產與流動負債的比率是否適當、有沒有即將到期的債務會影響公司財務
  21. 一家公司手上應該有多少現金才夠?Graham的建議是,流動資產至少是流動負債的兩倍才夠。另外一個評估財務強度的指標稱之為acid test,其條件是流動資產扣除庫存後,至少要等於流動負債,超過越多越好
  22. 分析資產負債表有三個重要的層面:(1) 檢查報表上中的EPS;(2) 確認損失或獲利對於公司財務報表中的影響;(3)  追蹤公司長期的resources 與 earning power 之間的關係
  23. 錯誤的價格無法持續太久
  24. 證券市場的估價常常是毫無邏輯且錯誤百出的,出價的過程不是自動或是有規劃的產生,完全是群眾的心理,而群眾的心理卻是最難理解的
  25. 人們在股市常犯的三個錯誤:誇大 (exaggeration), 過度簡化 (oversimplification) or 疏忽 (neglect)
  26. 試著想抓住市場的鐘擺是不可行的,你無法知道高點與低點在何時出現
  27. 標準的或大型的公司,其所發行的股票的股價,會針對其獲利數字做快速反應;一些較小型或比較不為人所熟悉的公司,則看市場的專業作手而決定,如果缺乏市場作手的興趣,其股價就會落後其營收表現;若得到市場作手關愛的眼神,則不管其營收表現,股價一樣一飛衝天
  28. 不要因為今年配發股利增加,就花更多的錢去追高
  29. 預測未來股價不是 security analysis 的工作
  30. 依照過去的歷史紀錄來預測未來有幾個問題:(1) 分析的行為本身並不科學,且無法讓你持續成功;(2) 不是個可靠的方法可以讓你在股市賺錢;(3) 理論基礎基於一個有缺陷的邏輯或僅僅是一個假說
  31. Security analysis 與 market analysis 的差異是,security analyst 會透過 margin of safety (安全邊際) 來保護自己 。Security analysis 強調為了面對未來可能的動盪,要做好安全邊際。若遭逢重大股災,至少有防護網做一定程度的保護,market analysis 則無此概念,若預測失誤,就只有賠錢的份
  32. Market forecasting 本身是一門藝術,其需要分析師的天賦、判斷力、直覺以及其他人格特質,沒有制式的規則或程序來保證預測成功。
  33. 在經濟的領域,具備科學性與完全可靠的預測方法,在邏輯上是不可能的
  34. 無論你是在華爾街或其他地方,沒有一個可靠的分析方法讓你容易且快速的賺錢
  35. 因為預測明年營收良好而受推薦的股票,有兩個地方要注意:ㄧ、有可能預測失準;二、即使預測正確,有可能現價已經貼現或過度貼現了
  36. 無論是那種分析方法或準備工作,成功的交易不是一種暫時與偶然,不然就是一種高度罕見的天賦。所以,大部分的投資人無可避免地都會以失敗收場
  37. Simple businesses with strong franchises can be run by any idiot.