在React中實(shí)現(xiàn)分塊導(dǎo)出大量數(shù)據(jù)表格并壓縮成圖片的解決方案
需求分析
我們的目標(biāo)是實(shí)現(xiàn)一個(gè)React組件,該組件能夠:
- 處理大量數(shù)據(jù)的表格展示。
- 將表格數(shù)據(jù)分塊導(dǎo)出為圖片。
- 壓縮導(dǎo)出的圖片以減少文件大小。
實(shí)現(xiàn)步驟
1. 獲取表格數(shù)據(jù)
首先,我們需要一個(gè)函數(shù)來(lái)獲取React表格組件的數(shù)據(jù)源:
const getTableData = (tableElement) => { const children = React.Children.only(tableElement.props.children); return children.props.dataSource || []; }
2. 創(chuàng)建帶數(shù)據(jù)的表格實(shí)例
接下來(lái),我們需要一個(gè)函數(shù)來(lái)創(chuàng)建一個(gè)新的表格實(shí)例,并更新其數(shù)據(jù)源:
const createTableWithData = (element, data) => { const tableInstance = React.Children.only(element.props.children); return React.cloneElement(tableInstance.props.children, { ...tableInstance.props.children.props, dataSource: data }); }
3. 分塊導(dǎo)出表格
為了處理大量數(shù)據(jù),我們將數(shù)據(jù)分塊,并為每個(gè)數(shù)據(jù)塊創(chuàng)建一個(gè)表格實(shí)例,然后導(dǎo)出為圖片:
const exportTableInChunks = async (element) => { const zip = new JSZip(); const tableElement = element.querySelector('.ant-table-wrapper'); const allData = getTableData(tableElement); const chunkSize = 200; const chunks = []; for (let i = 0; i < allData.length; i += chunkSize) { chunks.push(allData.slice(i, i + chunkSize)); } const exportContainer = document.createElement('div'); document.body.appendChild(exportContainer); const root = createRoot(exportContainer); try { const batchSize = 3; for (let i = 0; i < chunks.length; i += batchSize) { const currentBatch = chunks.slice(i, i + batchSize); await Promise.all( currentBatch.map(async (chunk, batchIndex) => { const newTable = createTableWithData(tableElement, chunk); root.render( <ConfigProvider theme={React.Children.only(children).props.children.props.theme}> {newTable} </ConfigProvider> ); await new Promise((resolve) => setTimeout(resolve, 2000)); const png = await exportElementAsPng(exportContainer, `${title}_part${i + batchIndex + 1}`); if (png) { zip.file( `${title}_part${i + batchIndex + 1}.png`, png.split('base64,')[1], { base64: true } ); } }) ); } const content = await zip.generateAsync({ type: 'blob' }); saveAs(content, `${title}.zip`); } finally { root.unmount(); document.body.removeChild(exportContainer); resetExportState(); } }
4. 導(dǎo)出操作的觸發(fā)
最后,我們需要一個(gè)函數(shù)來(lái)觸發(fā)導(dǎo)出操作,并處理錯(cuò)誤:
const handleExportContent = async (element) => { if (!element) { console.warn('Export element not found'); return; } try { const tableData = getTableData(element); if (tableData.length > 200) { await exportTableInChunks(element); } else { const res = await exportElementAsPng(element, title, 'single'); if (!res) { throw new Error('Failed to export image'); } } resetExportState(); } catch (error) { console.error('Export failed:', error); message.error('導(dǎo)出失敗,請(qǐng)重試'); } }
5.補(bǔ)充導(dǎo)出圖片的工具方法
- 需要注意批量導(dǎo)出的需要轉(zhuǎn)成base64然后壓縮,單張的直接走單圖片導(dǎo)出即可
import html2canvas from 'html2canvas' export const exportElementAsPng = ( element: HTMLElement, fileName: string = 'export', type?: string ) => { return new Promise((resolve, reject) => { // 添加最大尺寸限制 const maxDimension = 16384 // 大多數(shù)瀏覽器的 Canvas 最大尺寸限制 const elementRect = element.getBoundingClientRect() const scale = Math.min( 2, // 原來(lái)的 2 倍縮放 maxDimension / elementRect.width, maxDimension / elementRect.height ) html2canvas(element, { backgroundColor: null, scale: scale, logging: false, useCORS: true, // 允許跨域圖片 allowTaint: true, // 允許跨域圖片 windowWidth: element.scrollWidth, windowHeight: element.scrollHeight }) .then((canvas) => { // 創(chuàng)建下載鏈接 if(type==='single'){ const link = document.createElement('a') link.download = `${fileName}.png` link.href = canvas.toDataURL('image/png') link.click() resolve(true) }else{ const base64String = canvas.toDataURL(type) resolve(base64String) } }) .catch((error) => { reject(error) }) }) }
結(jié)語(yǔ)
通過(guò)上述步驟,我們實(shí)現(xiàn)了一個(gè)能夠處理React中大量數(shù)據(jù)表格的分塊導(dǎo)出與圖片壓縮的功能。這種方法不僅提高了性能,還優(yōu)化了用戶體驗(yàn),使得大量數(shù)據(jù)的導(dǎo)出變得更加高效和實(shí)用。
到此這篇關(guān)于在React中實(shí)現(xiàn)分塊導(dǎo)出大量數(shù)據(jù)表格并壓縮成圖片的解決方案的文章就介紹到這了,更多相關(guān)React導(dǎo)出數(shù)據(jù)表格并壓縮內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解React-Native解決鍵盤遮擋問(wèn)題(Keyboard遮擋問(wèn)題)
本篇文章主要介紹了React-Native解決鍵盤遮擋問(wèn)題(Keyboard遮擋問(wèn)題),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07從零開始學(xué)習(xí)搭建React腳手架項(xiàng)目
這篇文章主要介紹了從零開始學(xué)習(xí)搭建React腳手架項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08React Native react-navigation 導(dǎo)航使用詳解
本篇文章主要介紹了React Native react-navigation 導(dǎo)航使用詳解,詳解的介紹了react-navigation導(dǎo)航的使用,具有一定的參考價(jià)值,有興趣的可以了解一下2017-12-12react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果
本篇文章通過(guò)完整的代碼給大家介紹了react-player實(shí)現(xiàn)視頻播放與自定義進(jìn)度條效果,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-01-01npx create-react-app xxx創(chuàng)建項(xiàng)目報(bào)錯(cuò)的解決辦法
這篇文章主要介紹了npx create-react-app xxx創(chuàng)建項(xiàng)目報(bào)錯(cuò)的解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02react開發(fā)中如何使用require.ensure加載es6風(fēng)格的組件
本篇文章主要介紹了react開發(fā)中如何使用require.ensure加載es6風(fēng)格的組件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05React實(shí)現(xiàn)點(diǎn)擊刪除列表中對(duì)應(yīng)項(xiàng)
本文主要介紹了React 點(diǎn)擊刪除列表中對(duì)應(yīng)項(xiàng)的方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01