Converter: #CSV String to #TSV String

Converter: #CSV String to #TSV String

translate コンバータ: #CSV 文字列 to #TSV 文字列

Converts a CSV string to a TSV string. Line breaks and tab characters within cells enclosed in double quotes are replaced with half-width spaces. Excel-style double-quote escaping (consecutive double quotes) is replaced with a single character.

Auto Step icon
Configs for this Auto Step
StrConfA
A: Set Input CSV String *#{EL}
StrConfB1
B1: Set Replacement for Line Breaks (default: half-width space)#{EL}
StrConfB2
B2: Set Replacement for Tabs (default: half-width space)#{EL}
SelectConfC
C: Select String DATA to store Output TSV *
SelectConfD1
D1: Select NUMERIC for Number of TSV Lines (update)
SelectConfD2
D2: Select NUMERIC for Number of TSV Cols (update)
Script (click to open)
// Script Example of Business Process Automation
// for 'engine type: 3' ("GraalJS standard mode")


//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
const strInputCsv   = configs.get       ( "StrConfA" );     // REQUIRED
  if( strInputCsv === "" ){
    throw new Error( "\n AutomatedTask ConfigError: Config {A: CSV} is empty \n" );
  }
const strRepLb      = configs.get       ( "StrConfB1" ) || " "; // default
const strRepTab     = configs.get       ( "StrConfB2" ) || " "; // default
const strPocketC    = configs.getObject ( "SelectConfC" );  // REQUIRED
const numPocketD1   = configs.getObject ( "SelectConfD1" );
const numPocketD2   = configs.getObject ( "SelectConfD2" );



//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)



//// == Calculating / 演算 (SVG文字列の生成) ==

// 1. CSVからTSV文字列への変換(置換文字を引数で渡す)
const strOutputTsv = convertCsvToTsv(strInputCsv, strRepLb, strRepTab);

// 2. 行数・列数の算出(用意された関数を利用して2次元配列化)
const arr2dTsv = parseAsRectangular(strOutputTsv);
const numTotalLines = arr2dTsv.length;
const numCols = numTotalLines > 0 ? arr2dTsv[0].length : 0; // 1行目の要素数を列数とする



//// == Data Updating / ワークフローデータへの代入 ==

if ( strPocketC  !== null) { 
  engine.setData( strPocketC, strOutputTsv );
}
if ( numPocketD1 !== null) { 
  engine.setData( numPocketD1, new java.math.BigDecimal( numTotalLines ) );
}
if ( numPocketD2 !== null) { 
  engine.setData( numPocketD2, new java.math.BigDecimal( numCols ) );
}

} //////// END "main()" /////////////////////////////////////////////////////////////////




/**
 * Parses TSV string as a two-dimensional rectangular data matrix and creates a 2D array.
 * @date 2026-06-20
 * @author Questetra, Inc.
 * @license MIT
 * @param {string} strTsv - The input TSV string
 * @returns {Array<Array<string>>} Rectangular 2D array
 */
function parseAsRectangular( strTsv ){
  const arrTsv = strTsv.split("\n");
  let numMinWidth   = Infinity;
  let numMaxWidth   = 0;
  let numBlanklines = 0;
  
  const parsedRows = [];
  for( let i = 0; i < arrTsv.length; i++ ){
    const line = arrTsv[i];
    if( line === "" ){
      numBlanklines++;
      continue;
    }
    const arrCells = line.split("\t");
    const len = arrCells.length;
    if( len < numMinWidth ){ numMinWidth = len; }
    if( len > numMaxWidth ){ numMaxWidth = len; }
    parsedRows.push( arrCells );
  }
  
  if( numMinWidth === Infinity ){
    numMinWidth = 0;
  }
  engine.log( " AutomatedTask TsvDataCheck:" + 
              " MinWidth:" + numMinWidth +
              " MaxWidth:" + numMaxWidth +
              " Lines:" + arrTsv.length +
              " (BlankLines:" + numBlanklines + ")" );

  for( let i = 0; i < parsedRows.length; i++ ){
    const row = parsedRows[i];
    while( row.length < numMaxWidth ){
      row.push( "" );
    }
  }
  return parsedRows;
}




/**
 * Converts a CSV string to a TSV string. / CSV文字列をTSV文字列に変換する関数。
 * ---
 * - In-cell Line Breaks & Tabs:
 * Line breaks (\n, \r) and tabs (\t) enclosed in double quotes are converted into half-width spaces.
 * - Escaped Quotes:
 * Secured Excel-style escaped double quotes ("") and treats them as a single literal quote.
 * - Newline Support:
 * Supports CR, LF, and CRLF as line separators. Output line breaks are unified to LF (\n).
 * ---
 * - セル内の改行・タブ:
 * ダブルクオートに囲まれたセル内の改行およびタブは、半角スペースに置換されます。
 * - クオートのエスケープ:
 * Excel形式のダブルクオートのエスケープ("")を認識し、1つの文字として処理します。
 * - 改行コード対応:
 * CR, LF, CRLF の各改行コードに対応。出力時の改行は LF (\n) に統一されます。
 * ---
 * @date 2026-06-20
 * @author Questetra, Inc.
 * @license MIT
 * @param {string} csvText - Input CSV string / 変換元のCSV文字列
 * @param {string} repLb - 改行コードの置換文字列
 * @param {string} repTab - タブの置換文字列
 * @returns {string} TSV formatted string / TSV形式の文字列
 */
function convertCsvToTsv(csvText, repLb, repTab) {
  let lines = [];
  let row = [""];
  let inQuotes = false;

  for (let i = 0; i < csvText.length; i++) { 
    let c = csvText[i];
    let next = csvText[i + 1];

    if (inQuotes) {
      if (c === '"') {
        if (next === '"') { 
          // "" はエスケープされたダブルクオート
          row[row.length - 1] += '"';
          i++; 
        } else { 
          // 閉じダブルクオート
          inQuotes = false;
        }
      } else {  
        // ====== ダブルクオートに囲まれた「セル内」の置換処理 ======
        if (c === '\r' && next === '\n') {
          // CRLFの場合は1つの改行として扱い、iを1つ進める
          row[row.length - 1] += repLb;
          i++;
        } else if (c === '\n' || c === '\r') {
          // LF または CR 単独の場合
          row[row.length - 1] += repLb;
        } else if (c === '\t') {
          // タブの場合
          row[row.length - 1] += repTab;
        } else {
          // 通常の文字
          row[row.length - 1] += c;
        }
      }
    } else {
      // ====== セル外(通常のCSV区切り・行区切り)の処理 ======
      if (c === '"') {
        inQuotes = true;
      } else if (c === ',') {
        row.push(""); // 次の列へ
      } else if (c === '\r' || c === '\n') {  
        if (c === '\r' && next === '\n') i++; // CRLF対応
        lines.push(row);
        row = [""];
      } else {
        row[row.length - 1] += c;
      }
    }
  }
  // 最終行の追加
  if (row.length > 1 || row[0] !== "") {
    lines.push(row);
  }

  return lines.map(fields => fields.join('\t')).join('\n');
}





/*
### NOTES-en
- A TSV string is automatically generated each time a Case reaches this Automated Step.
    - Refers to the input CSV string.
    - If the cell data is enclosed in double quotes, the enclosing double quotes are removed.
    - Line breaks and tab characters within cells are replaced with half-width spaces.
        - It is also possible to configure replacement strings other than a "half-width space".
        - Example 3 shows the output when "★" is set as the replacement for line breaks and "◆" for tabs.
    - Recognizes Excel-style double-quote escaping (consecutive double quotes `""`) and treats them as a single literal quote (`"`).

### NOTES-ja
- このアドオン自動工程にケース(案件)が到達する度に、自動的に TSV 文字列が生成されます。
    - CSV 文字列を参照します。
    - セルデータがダブルクオートに囲まれている場合、ダブルクオートは削除されます。
    - セル内にある改行コードとタブコードは半角スペースに置換されます。
        - 置換文字列を「半角スペース」以外に設定するコトも可能です。
        - InputCSV 3 の例: 改行の置換文字列に「★」、タブの置換文字列に「◆」を設定した場合の出力。
    - Excel形式のダブルクオートのエスケープ("")を認識し、1つの文字として処理します。


#### InputCSV OutputTSV examples
- InputCSV 1:
    - `"99","2026/04/01","売上高","SaaS","","","課売 10%","","前受金",`
- OutputTSV 1:
    - `99	2026/04/01	売上高	SaaS			課売 10%		前受金	`
- InputCSV 2:
    - `99,2026/04/01,売上高,SaaS,,"","課売 10%","","前受金",`
- OutputTSV 2:
    - `99	2026/04/01	売上高	SaaS			課売 10%		前受金	`
- InputCSV 3:
    - `"ID","摘要","金額"`
    - `"100001","1行目	←ここはタブ`
    - `2行目","3300"`
    - `"100002","商品名 ""A4コピー用紙""	100冊`
    - `見積番号:Q2026","12000"`
- OutputTSV 3:
    - `ID	摘要	金額`
    - `100001	1行目◆←ここはタブ★2行目	3300`
    - `100002	商品名 "A4コピー用紙"◆100冊★見積番号:Q2026	12000`


### APPENDIX-en
- Supports CR, LF, and CRLF as line separators.
    - Output line breaks are unified to LF (\n).

### APPENDIX-ja
- CR, LF, CRLF の各改行コードに対応しています。
    - 出力時の改行は LF (\n) に統一されます。
*/


Download

warning Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.
(Installing Addon Auto-Steps are available only on the Professional edition.)

Notes

  • A TSV string is automatically generated each time a Case reaches this Automated Step.
    • Refers to the input CSV string.
    • If the cell data is enclosed in double quotes, the enclosing double quotes are removed.
    • Line breaks and tab characters within cells are replaced with half-width spaces.
      • It is also possible to configure replacement strings other than a “half-width space”.
      • Example 3 shows the output when “★” is set as the replacement for line breaks and “◆” for tabs.
    • Recognizes Excel-style double-quote escaping (consecutive double quotes "") and treats them as a single literal quote (").

Capture

Appendix

  • Supports CR, LF, and CRLF as line separators.
    • Output line breaks are unified to LF (\n).

See also

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading