背景:因公司业务需要,需要对一些网站的表格数据进行拉取整理到Excel,采用谷歌插件的方式去实现
第一个问题:需要拉取的页面存在下拉滚动条,页面数据是下拉滚动请求接口获取的,如果直接获取当前可视区域的数据,会造成数据获取不全的问题
解决方法:通过计算滚动区域和可视区域的高度,计算滚动次数,页面数据请求接口并组装呈现,需要使用延时处理
var totalHeight = $('.xxx').height();
// 屏幕长度
var clientHeight = document.body.clientHeight;
// 需要滚动的次数
let numbers = Number((totalHeight / clientHeight).toFixed(0));
const isZero = totalHeight % clientHeight;
numbers = isZero === 0 ? numbers : numbers + 1;
// 进行下拉滚动加载数据
// 等页面下拉到底的时候,在进行页面dom获取
new Promise((reslove, reject) => {
for (let i = 0; i < numbers; i++) {
(function (i) {
setTimeout(() => {
const heigth = i * clientHeight;
// 页面滚动
$('.xxx-container').scrollTop(heigth);
if (i + 1 === numbers) {
reslove(true);
}
}, i * 5000);
})(i);
}
}).then((res) => {
// 页面dom获取操作处理
})
第二个问题:导出页面的图,最初的方案是通过html2canvas这个插件去做的,但是之后遇到一个问题,就是我下拉滚动后,图消失在可视区域,而html2canvas这个插件,只能捕获可视区域的图,所以导出的图是空白的(即便后来通过定位显示对应的图到可视区域,但是好像还是不行,这一点暂时没想明白)
解决方法:使用dom-to-image 这个插件 这个插件支持导出png,svg,jpeg等,但是也有问题,就是只有svg和png格式的导出能够让wps识别,其余格式导出,window自带的和wps都不能识别出来,这点暂时没有解决方法
// 获取页面存在的图的dom
let htmls = '';
var chartArr = $('.xxx-chart');
let chartFlag = 0;
if (chartArr && chartArr.length > 0) {
chartArr.each(async function (index, element) {
await domtoimage.toPng(chartArr[index]).then((dataUrl) => {
const title = $(this)
.parents('.fx-dash-container')
.find('.header-title')
.text();
htmls += `<div class="fx-dash-container dash-widget has-hover"
data-source="_widget_1660386101934#62dfd52b2910e50007659a41@62d0c5e8fb06c500077ab520"
style="background: rgb(0, 0, 255); top: 1737px; left: 20px; width: 526.667px; height: 320px;">
<div class="container-header" style="color: rgb(31, 45, 61);">
<div class="header-title">${title}</div>
</div>
<div class="container-content">
<div class="fx-dash-chart"
vancharts_index_="vancharts_index_1"
style="overflow: hidden;
width: 526.667px;
height: 320px;
user-select: none;
touch-action: manipulation;
-webkit-user-drag: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<img style=" width: 526.667px; height: 320px;" src="${dataUrl}" />
</div>
</div>
</div>`;
chartFlag += 1;
});
}
if (chartFlag == chartArr.length) {
// 图表导出处理
}
第三个问题:在表格有分页的时候,会进行模拟翻页点击,并获取当前table结构组装到之前的数据结构上,但是在对页面dom进行了处理后,即便你在处理之前获取的dom结构,对页面dom处理后,再次打印之前获取的dom结构,会显示为处理之后的dom结构。这点在做表格分页数据获取的时候很难处理;
解决方案:首先是拿到分页数,循环拿到所有的分页表格数据,在组装到第一页的表格数据的时候,需要将页数切换到第一页,否则组装出来的数据,就是表格最后页的数据加上分页遍历出来的数据
if ($(parent).find('.x-pagination')) {
const totalPageText = $(parent)
.find('.x-pagination .total-page')
.text()
.replace(/[\/]/g, '')
.trim();
const totalPage = totalPageText && Number(totalPageText);
let appendHtml = '';
if (totalPage !== 1) {
const numbers = totalPage - 1;
for (let k = 0; k < numbers; k++) {
$(parent).find('.page-turn-next').click();
const tableCurrentContent =
$(parent).find('table tbody')[0];
appendHtml += tableCurrentContent.innerHTML;
}
$('.page-turn-first').click();
$(parent).find('table tbody').append(appendHtml);
}
$(parent).find('.x-pagination').remove();
parents.push(...parent);
第四个问题:导出比较好看的表格
let tableName = '';
let htmls = ''
;var exportFileContent =
'<html xmlns:x="urn:schemas-microsoft-com:office:excel"><head><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>' +
tableName +
'</x:Name><x:WorksheetOptions><x:Print><x:ValidPrinterInfo /></x:Print></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml></head>' +
htmls +
'</html>';
var blob = new Blob([exportFileContent], {
type: 'text/plain;charset=utf-8',
});
blob = new Blob([String.fromCharCode(0xfeff), blob], {
type: blob.type,
});