我是使用 XLSX 包的新手,我不太确定如何创建特定的标题,包括颜色和特定于组的列。
我需要做一些事情作为视觉示例
在标题下,我可以有几个列,标题有颜色。 每个标题的列不是固定的,所以我们可以在另一个有 5 列的标题下有一个 2 列的标题。
我开始做一些基本的事情并分享了我的代码,但我不知道如何制作标题作为例子。该代码用于我正在处理的项目中 XLS 中的报告提取器
import XLSX from 'xlsx';
import moment from 'moment';
const rawToHeaders = ({
id,
externalIds,
dateOfBirth = {},
postalCode,
locale,
siteId,
status = {},
prescreenerMetrics,
}) => {
const { day, month, year } = dateOfBirth;
const dob = [day, month, year].filter(Boolean).join('-');
const { type, label, comment, timestamp } = status;
const timeInStatus = moment(timestamp).toNow(true);
const N_A = 'not available';
return {
'Candidate ID': id,
'External IDs': externalIds
?.map(({ source, value }) => `${source}: ${value}`)
.join('; '),
'Date of birth': dob,
'Postal code': postalCode,
Locale: locale,
'Site ID': siteId,
'Current status': type,
'Current sub-status': label,
'Current status comment': comment,
'Time in current status': timeInStatus,
'Source/recruiter': prescreenerMetrics?.source,
Referrer: prescreenerMetrics?.referrer,
};
};
const generateMasterReport = (data) => {
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.json_to_sheet(data.map(rawToHeaders));
XLSX.utils.book_append_sheet(wb, ws);
return XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' });
};
export default generateMasterReport;
在上面的代码中,假设我想用颜色对特定标题下的列进行分组
列是 12,所以 4 个标题和顺序,就像代码中一样
我现在可以创建没有标题的 excel,但这部分我不知道该怎么做
我找到了解决我的问题的方法,但我不知道它是否是最好的 :) 但是,为我工作所以我分享
在我所做的代码下面,我将标题放在一个用于创建标题的变量中,我使用文档中的“合并”来创建标题的合并单元格。
我不知道的是如何使它更具功能性以及如何为单个列而不是全局列创建一个 with
const colWidths = [{ wch: 12 }];
我想将每一列自定义为特定宽度。
另一件事我相信如果没有 PKG 的专业版,我无法使用不同的字体、BGColor 等设置单元格的样式,但如果有办法,我很高兴 :)
import XLSX from 'xlsx';
import moment from 'moment';
const N_A = null;
const headerGroups = [
{ name: 'Candidate data', origin: 'A1' },
{ name: 'Date receiving status', origin: 'N1' },
{ name: 'Candidate in Pending call center status', origin: 'U1' },
{
name: 'Candidate in Pending site OR Consented OR Randomized status',
origin: 'AI1',
},
];
const colWidths = [{ wch: 12 }];
const rawToHeaders = ({
id,
externalIds,
dateOfBirth = {},
postalCode,
locale,
siteId,
status = {},
prescreenerMetrics,
}) => {
const { day, month, year } = dateOfBirth;
const dob = [day, month, year].filter(Boolean).join('-');
const { type, label, comment, timestamp } = status;
const timeInStatus = moment(timestamp).toNow(true);
return {
// !Candidate data
'Candidate ID': id,
'External IDs': externalIds
?.map(({ source, value }) => `${source}: ${value}`)
.join('; '),
'Date of birth': dob,
'Postal code': postalCode,
Locale: locale,
'Site ID': siteId,
'PI name': N_A,
'Current status': type,
'Current sub-status': label,
'Current status comment': comment,
'Time in current status': timeInStatus,
'Source/recruiter': prescreenerMetrics?.source,
Referrer: prescreenerMetrics?.referrer,
// !Date receiving status
'Pending call center': N_A,
'Pending site': N_A,
Consented: N_A,
Randomized: N_A,
'Rejected call center': N_A,
'Rejected site (+ rejected_consented + rejected_randomized)': N_A,
'Call Scheduled': N_A,
// !Candidate in Pending call center status
'Call - Attempts (by call center)': N_A,
'SMS - Attempts (by call center)': N_A,
'Email - Attempts (by call center)': N_A,
'Phone number revealed (by call center) - quantity': N_A,
'Email revealed (by call center) - quantity': N_A,
'Call - date of first attempt (by call center)': N_A,
'SMS - date of first attempt (by call center)': N_A,
'Email - date of first attempt (by call center)': N_A,
'Call - duration of longest call (by call center)': N_A,
'Call - date of longest call (by call center)': N_A,
'Comments (by call center) in Trialbee system': N_A,
'Last staff activity (by call center) - Action': N_A,
'Last staff activity by call center - User': N_A,
'Last staff activity by call center - Date': N_A,
// !Candidate in Pending site OR Consented OR Randomized status
'Call - attempts (by site)': N_A,
'SMS - attempts (by site)': N_A,
'Email - attempts (by site)': N_A,
'Phone number revealed (by site) - quantity': N_A,
'Email revealed (by site) - quantity': N_A,
'Call - date of first attempt (by site)': N_A,
'SMS - date of first attempt (by site)': N_A,
'Email - date of first attempt by site': N_A,
'Call - Longest duration of call (by site)': N_A,
'Call - Date of longest call (by site)': N_A,
'Comments (by site) in Trialbee system': N_A,
'Last staff activity (by site) - Action': N_A,
'Last staff activity (by site) - User': N_A,
'Last staff activity (by site) - Date': N_A,
};
};
const generateMasterReport = (data) => {
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.json_to_sheet(data.map(rawToHeaders), { origin: 'A2' });
ws['!merges'] = [
XLSX.utils.decode_range('A1:M1'),
XLSX.utils.decode_range('N1:T1'),
XLSX.utils.decode_range('U1:AH1'),
XLSX.utils.decode_range('AI1:AV1'),
];
headerGroups.forEach(({ name, origin }) => {
XLSX.utils.sheet_add_aoa(ws, [[name]], { origin });
});
ws['!cols'] = colWidths;
XLSX.utils.book_append_sheet(wb, ws);
return XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' });
};
export default generateMasterReport;
您可以通过在数组中给出 wch 值来设置每列的宽度
const wb = XLSX.utils.book_new();
const colWidths = [{ wch: 12 },{ wch: 20 },{ wch: 25 },{ wch: 30 },{ wch: 40 }];
ws['!cols'] = colWidths;
XLSX.utils.book_append_sheet(wb, ws);