在React中实现分块导出大量数据表格并压缩成图片的解决方案
需求分析
我们的目标是实现一个React组件,该组件能够:
- 处理大量数据的表格展示。
- 将表格数据分块导出为图片。
- 压缩导出的图片以减少文件大小。
实现步骤
1. 获取表格数据
首先,我们需要一个函数来获取React表格组件的数据源:
const getTableData = (tableElement) => {
const children = React.Children.only(tableElement.props.children);
return children.props.dataSource || [];
}
2. 创建带数据的表格实例
接下来,我们需要一个函数来创建一个新的表格实例,并更新其数据源:
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. 分块导出表格
为了处理大量数据,我们将数据分块,并为每个数据块创建一个表格实例,然后导出为图片:
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. 导出操作的触发
最后,我们需要一个函数来触发导出操作,并处理错误:
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('导出失败,请重试');
}
}
5.补充导出图片的工具方法
- 需要注意批量导出的需要转成base64然后压缩,单张的直接走单图片导出即可
import html2canvas from 'html2canvas'
export const exportElementAsPng = (
element: HTMLElement,
fileName: string = 'export',
type?: string
) => {
return new Promise((resolve, reject) => {
// 添加最大尺寸限制
const maxDimension = 16384 // 大多数浏览器的 Canvas 最大尺寸限制
const elementRect = element.getBoundingClientRect()
const scale = Math.min(
2, // 原来的 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) => {
// 创建下载链接
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)
})
})
}
结语
通过上述步骤,我们实现了一个能够处理React中大量数据表格的分块导出与图片压缩的功能。这种方法不仅提高了性能,还优化了用户体验,使得大量数据的导出变得更加高效和实用。
到此这篇关于在React中实现分块导出大量数据表格并压缩成图片的解决方案的文章就介绍到这了,更多相关React导出数据表格并压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解决React报错`value` prop on `input` should&
这篇文章主要为大家介绍了React报错`value` prop on `input` should not be null解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-12-12
react redux中如何获取store数据并将数据渲染出来
这篇文章主要介绍了react redux中如何获取store数据并将数据渲染出来,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-08-08
基于Cloud Studio构建React完成点餐H5页面(腾讯云 Cloud Studio 实战训练营)
最近也是有机会参与到了腾讯云举办的腾讯云Cloud Studio实战训练营,借此了解了腾讯云Cloud Studio产品,下面就来使用腾讯云Cloud Studio做一个实战案例来深入了解该产品的优越性吧,感兴趣的朋友跟随小编一起看看吧2023-08-08
React Native 中处理 Android 手机吞字的解决方案
这篇文章主要介绍了React Native 中处理 Android 手机吞字的解决方案,作者在 React Native 0.67.4 环境下,编写了一个小 demo 来复现这个问题,需要的朋友可以参考下2022-08-08


最新评论