1.問題原因:我們在界面填寫好數據之後並生成excel,如果數據中是以"=+-@"開頭,那麼在我們Excel裏面顯示的時候會出現CSV Injection問題。
2.如何解決:
- 2.1解決思路:首先生成Excel的workbook,之後再遍歷這個workbook,如果遇到以這些特殊字符開頭的數據,那麼把這些數據拿到之後,在其前面加一個TAB鍵。
3.核心代碼:
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public static void formulaInjectionScan(Workbook wb)
{
if (null == wb)
{
return;
}
for (Sheet sheet : wb)
{
for (Row row : sheet)
{
for (Cell cell : row)
{
if (CellType.STRING == cell.getCellTypeEnum())
{
String cellVal = cell.getStringCellValue();
if (StringUtils.isNotBlank(cellVal) && cellVal.length() > 1 && !NumberUtils.isNumber(cellVal)
&& cellVal.matches(FORMULA_REGEX))
{
cell.setCellValue(TAB + cellVal);
}
}
}
}
}
}
4.引入新的問題:雖然CSV Injection問題處理好了,但是生產的Excel如果上傳到我們的系統裏面,那麼界面上展示的跟CSV Injection相關的數據,這部分數據會顯示TAB鍵,這不是用戶想要的結果。
- 4.1處理引入新的問題:其實很簡單,我們在上傳Excel模板的接口中只需要把TAB打頭的給過濾掉即可。
- 4.2 代碼如下:
import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; public static void removePrefixedTabSpace(Workbook wb) { if (null == wb) { return; } for (Sheet sheet : wb) { for (Row row : sheet) { for (Cell cell : row) { if (CellType.STRING == cell.getCellTypeEnum()) { String cellVal = cell.getStringCellValue(); if (StringUtils.isNotBlank(cellVal) && cellVal.startsWith(String.valueOf(TAB))) { cell.setCellValue(cellVal.replaceFirst(String.valueOf(TAB), "")); } } } } } }