【utils】前端導(dǎo)出數(shù)據(jù):csv與txt【2023-02-21】

介紹

目前代碼支持兩種導(dǎo)出方式:

  • csvExport:導(dǎo)出為csv格式
  • plainExport:純文本形式導(dǎo)出风题,默認(rèn)后綴為txt

模塊要求:

  • antd

csvExport

import { message } from 'antd';

const csvExport = (data, fileName='export.csv', removeColName = false, separator=',') => {

    /*csv download*/
    if (data.length === 0) {
        message.warn("NO such data. Please reset the search criteria.");
    } else {
        const cols = Object.keys(data[0]);
        let blobData = '\uFEFF'  // BOM head, make excel know it is csv.
        if (!removeColName) {
            blobData += cols.join(separator) + '\n';  // add column name

        }
        console.log('prepare to download. data is ', data);
        data.forEach(
            item => {
                const itemData = []
                cols.forEach(col => {
                    // console.log(ele, index)
                    const val = item[col] || '-';
                    itemData.push(`"${val}"`)
                })
                blobData += `${itemData.join(separator)}\n`;

            }
        );
        const export_uri = `data:text/csv;charset=utf-8,${encodeURIComponent(blobData)}`;
        const a = document.createElement('a');
        a.style.display = 'none';
        a.setAttribute('target', '_blank');
        a.setAttribute('download', fileName);
        a.href = export_uri;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }
}

參數(shù)data為要導(dǎo)出的數(shù)據(jù),要求格式為列表幽勒,列表元素為對象羽历。如果data為空會報(bào)錯(cuò)焊虏。
當(dāng)data不為空時(shí),會以data的第一個(gè)元素的key值作為列名秕磷。默認(rèn)是要輸出列名的诵闭,如果不想在導(dǎo)出的文件中包含列名,可以將removeColName設(shè)置為True澎嚣。
另外疏尿,默認(rèn)情況下csv中每一行的分隔符是逗號,但其他的如制表符其實(shí)也可以易桃。如果想使用除逗號之外的分隔符褥琐,可以將其傳遞給separator參數(shù)。

準(zhǔn)備導(dǎo)出數(shù)據(jù)的部分并不復(fù)雜晤郑,其實(shí)就是將data中元素的每一個(gè)值挨個(gè)取出敌呈,用separator拼接在一起形成一個(gè)字符串贸宏,然后元素和元素之間(可以理解為行與行之間)用\n分隔即可。

?暮椤吭练!注意:需要保證data中每一個(gè)元素的key相同,否則只會取第一個(gè)元素中包含的key做導(dǎo)出文件的列析显。

在導(dǎo)出內(nèi)容整理好之后鲫咽,就通過添加超鏈接節(jié)點(diǎn)的方式觸發(fā)下載,也就是const export_uri = `data:text/csv;charset=utf-8,${encodeURIComponent(blobData)}`;及之后的代碼谷异。

plainExport

const plainExport = (data, fileName='export.txt') => {
    let blobData = data

    const export_uri = `data:text/plain;charset=utf-8,${encodeURIComponent(blobData)}`;
    const a = document.createElement('a');
    a.style.display = 'none';
    a.setAttribute('target', '_blank');
    a.setAttribute('download', fileName);
    a.href = export_uri;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

}

邏輯更加簡單分尸,即“無腦地”將輸入的參數(shù)進(jìn)行導(dǎo)出。這里歹嘹,要求data為字符串結(jié)構(gòu)箩绍,由后臺代碼來控制每一行列分別是什么樣子。比如在我的項(xiàng)目中荞下,先將dataframe的多列拼接成由逗號分隔各列內(nèi)容的單列伶选,然后將其轉(zhuǎn)為list,最后用換行符拼接成一個(gè)字符串尖昏。這樣的字符串經(jīng)由plainExport()導(dǎo)出,其形如csv构资,但添加了在csv中不太好操作的一些格式化內(nèi)容抽诉,用以滿足用戶的需求:

# python
joined_series = None
for col_index in range(len(df.columns)):
    if col_index == 0:
        joined_series = "  "+df[df.columns[col_index]]  # first col, start with two space
    elif col_index == len(df.columns) -1:
        # last col, start with ",", no spaces
        joined_series += ","+df[df.columns[col_index]]
    else:
        # middle cols, start with ",....", "." is space
        joined_series += ",    " + df[df.columns[col_index]]

logger.debug("Join all columns of df is done.")

if joined_series is None:
    raise Exception(f"No columns can be got")

logger.debug(str(joined_series))
joined_series_list = joined_series.tolist()
return_content = "\n".join(joined_series_list)
return return_content

完整code

import { message } from 'antd';


const csvExport = (data, fileName='export.csv', removeColName = false, separator=',') => {

    /*csv download*/
    if (data.length === 0) {
        message.warn("NO such data. Please reset the search criteria.");
    } else {
        const cols = Object.keys(data[0]);
        let blobData = '\uFEFF'  // BOM head, make excel know it is csv.
        if (!removeColName) {
            blobData += cols.join(separator) + '\n';  // add column name

        }
        console.log('prepare to download. data is ', data);
        data.forEach(
            item => {
                const itemData = []
                cols.forEach(col => {
                    // console.log(ele, index)
                    const val = item[col] || '-';
                    itemData.push(`"${val}"`)
                })
                blobData += `${itemData.join(separator)}\n`;

            }
        );
        // console.log('prepare export', blobData);
        const export_uri = `data:text/csv;charset=utf-8,${encodeURIComponent(blobData)}`;
        const a = document.createElement('a');
        a.style.display = 'none';
        a.setAttribute('target', '_blank');
        a.setAttribute('download', fileName);
        a.href = export_uri;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }


}


const plainExport = (data, fileName='export.txt') => {
    let blobData = data

    const export_uri = `data:text/plain;charset=utf-8,${encodeURIComponent(blobData)}`;
    const a = document.createElement('a');
    a.style.display = 'none';
    a.setAttribute('target', '_blank');
    a.setAttribute('download', fileName);
    a.href = export_uri;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

}


export {
    csvExport,
    plainExport
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吐绵,隨后出現(xiàn)的幾起案子迹淌,更是在濱河造成了極大的恐慌,老刑警劉巖己单,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唉窃,死亡現(xiàn)場離奇詭異,居然都是意外死亡纹笼,警方通過查閱死者的電腦和手機(jī)纹份,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廷痘,“玉大人蔓涧,你說我怎么就攤上這事∷穸睿” “怎么了元暴?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兄猩。 經(jīng)常有香客問我茉盏,道長鉴未,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任鸠姨,我火速辦了婚禮铜秆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘享怀。我一直安慰自己羽峰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布添瓷。 她就那樣靜靜地躺著梅屉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳞贷。 梳的紋絲不亂的頭發(fā)上坯汤,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音搀愧,去河邊找鬼惰聂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛咱筛,可吹牛的內(nèi)容都是我干的搓幌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼迅箩,長吁一口氣:“原來是場噩夢啊……” “哼溉愁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饲趋,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拐揭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奕塑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堂污,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年龄砰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盟猖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寝贡,死狀恐怖扒披,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情圃泡,我是刑警寧澤碟案,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站颇蜡,受9級特大地震影響价说,放射性物質(zhì)發(fā)生泄漏辆亏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一鳖目、第九天 我趴在偏房一處隱蔽的房頂上張望扮叨。 院中可真熱鬧,春花似錦领迈、人聲如沸彻磁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衷蜓。三九已至,卻和暖如春尘喝,著一層夾襖步出監(jiān)牢的瞬間磁浇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工朽褪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留置吓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓缔赠,卻偏偏與公主長得像衍锚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子嗤堰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容