努力当上钱厚端 2024-02-04 07:43 采纳率: 30.4%
浏览 435

exceljs 导出表格怎么设置列宽自适应表头和表体两个条件自动撑开?

这列数据看起来好挤

img

想要两个自动

  1. 表头比数据宽就按表头
  2. 数据比表头宽就按数据

比如:

img

  • 写回答

2条回答

  • 努力当上钱厚端 2024-02-05 03:01
    关注

    完美,哈哈哈哈

    img

    export function exportExcel(headers = [], data = [], name = 'excel') {
      // 创建工作簿
      const workbook = new ExcelJS.Workbook()
      // 添加工作表
      const worksheet = workbook.addWorksheet('sheet1')
    
      // 设置表头
      worksheet.columns = headers
    
      const border = {
        top: {
          style: 'thin',
        },
        left: {
          style: 'thin',
        },
        bottom: {
          style: 'thin',
        },
        right: {
          style: 'thin',
        },
      }
    
      // 添加数据
      data.map((row, index) => {
        worksheet.addRow(row)
        worksheet.columns.map((column) => {
          // 表头的样式
          worksheet.getCell(`${column.letter}1`).border = border
          worksheet.getCell(`${column.letter}1`).font = {
            bold: true,
          }
          worksheet.getCell(`${column.letter}1`).fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: { argb: 'FF8FBC8F' },
          }
    
          // 列宽自适应
          let width = []
          column.values.map((value) => {
            if (!value) {
              width.push(10)
            } else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
              width.push(parseFloat(value.toString().length * 2.15))
            } else {
              width.push(parseFloat(value.toString().length * 1.15))
            }
          })
          column.width = Math.max(...width)
    
          // 行数据的样式
          worksheet.getCell(`${column.letter}${index + 2}`).border = border
        })
      })
    
      // 导出表格
      // workbook.xlsx.writeFile('测试' + '.xlsx') // 报错
      workbook.xlsx.writeBuffer().then((buffer) => {
        const blob = new Blob([buffer], {
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        })
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = name + '.xlsx'
        link.click()
        URL.revokeObjectURL(link.href) // 下载完成释放掉blob对象
      })
    }
    

    展开全部

    评论
    努力当上钱厚端 2024-10-14 05:31

    如果想要数据验证,有下拉框的单元格。可以设置 dataValidation

    img

                      if (headers[i].formulae) {
                                // 设置数据校验
                                worksheet.getCell(`${column.letter}${index+2}`).dataValidation = {
                                    type: "list",
                                    allowBlank: true,
                                    formulae: headers[i].formulae,
                                };
                            };
    

    表头的数据这样传:

    img

    传入formulae字段。格式就是 [一个逗号隔开的字符串]

    img

    回复
  • 叫兽-郭老师 Java领域新星创作者 2024-02-04 07:51
    关注

    参考通义千问和郭老师的小迷弟雅思莫了-编写提供,主要是为了帮助您快速解决问题,如下回答,您可以参考下,如有问题,评论区留言。

    ExcelJS 是一个用于处理和生成 Excel (.xlsx) 文件的 JavaScript 库,但它并不直接支持列宽自动调整为完全匹配内容宽度的功能。在 ExcelJS 中设置列宽时,你需要手动指定每个列的宽度。

    尽管如此,你可以尝试以下方法来尽量模拟这种效果:

    1. 获取最大宽度

      • 在填充数据到工作表之前,可以遍历你的数据源,针对每一列计算出所有单元格内容的最大宽度。
      • 使用 getTextWidth 这样的库(或者自定义函数)计算字符串在默认字体、字号下的像素宽度,然后转换成 Excel 的列宽单位(例如,Excel 的列宽最小单位是 0.125 字符宽度)。
    2. 设置列宽

      • 根据上一步得到的最大宽度,使用 worksheet.getColumn(columnNumber).width = maxWidthInChars; 来设置每列的宽度。

    下面是一个简化的示例逻辑:

    // 假设 data 是二维数组,表示表格数据
    const data = [
      ['Header 1', 'Very Long Data Entry'],
      // ...
    ];
    
    // 获取每列最大宽度(这里仅作示意,实际需要实现文本宽度计算)
    let columnWidths = {};
    data.forEach(row => {
      row.forEach((cell, index) => {
        if (!columnWidths[index]) {
          columnWidths[index] = cell.length;
        } else {
          columnWidths[index] = Math.max(columnWidths[index], cell.length);
        }
      });
    });
    
    // 设置列宽
    Object.entries(columnWidths).forEach(([index, width]) => {
      worksheet.getColumn(index + 1).width = width * someFactor; // 考虑到字符宽度与字符数的比例,可能需要乘以某个系数
    });
    

    请注意上述代码仅为示例,并未考虑到文本的实际渲染宽度(换行、特殊字符等),若要精确匹配,你可能需要借助更为复杂的文本测量技术或预览生成后的 Excel 文件进行微调。目前 ExcelJS 并不具备原生的“根据内容自动调整列宽”功能。

    展开全部

    评论
    努力当上钱厚端 2024-10-14 05:33

    img

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>exceljs 使用</title>
        </head>
        <body>
            <button onclick="exporting()">导出</button>
    
    
    
            <script>
                function exporting() {
                    exportExcel(
                        // 表头
                        [{
                                header: '名次',
                                key: 'sort',
                            },
                            {
                                header: '班级',
                                key: 'class',
                            },
                            {
                                header: '姓名',
                                key: 'name'
                            },
                            {
                                header: '得分',
                                key: 'score',
                            },
                            {
                                header: '等级',
                                key: 'level',
                                formulae: ['"值1,值2,值3"'] // 格式就是这样  https://github.com/exceljs/exceljs/blob/master/README_zh.md#%E6%95%B0%E6%8D%AE%E9%AA%8C%E8%AF%81
                            },
                        ],
                        // 数据
                        [{
                                sort: 1,
                                class: '前端三班',
                                name: 'Buer',
                                score: 99
                            },
                            {
                                sort: 2,
                                class: '前端二班',
                                name: 'Jack',
                                score: 86
                            },
                            {
                                sort: 3,
                                class: '前端一班',
                                name: 'Mary',
                                score: 58
                            }
                        ]
                    )
                };
    
                function exportExcel(headers = [], data = [], name = 'excel') {
                    // 创建工作簿
                    const workbook = new ExcelJS.Workbook()
                    // 添加工作表
                    const worksheet = workbook.addWorksheet('sheet1')
    
                    // 设置表头
                    worksheet.columns = headers
    
                    const border = {
                        top: {
                            style: 'thin',
                        },
                        left: {
                            style: 'thin',
                        },
                        bottom: {
                            style: 'thin',
                        },
                        right: {
                            style: 'thin',
                        },
                    }
    
                    // 添加数据
                    data.map((row, index) => {
                        worksheet.addRow(row)
                        worksheet.columns.map((column, i) => {
                            if (headers[i].formulae) {
                                // 设置数据校验
                                worksheet.getCell(`${column.letter}${index+2}`).dataValidation = {
                                    type: "list",
                                    allowBlank: true,
                                    formulae: headers[i].formulae,
                                };
                            };
                            // 表头的样式
                            worksheet.getCell(`${column.letter}1`).border = border
                            worksheet.getCell(`${column.letter}1`).font = {
                                bold: true,
                            }
                            worksheet.getCell(`${column.letter}1`).fill = {
                                type: 'pattern',
                                pattern: 'solid',
                                fgColor: {
                                    argb: 'FF8FBC8F'
                                },
                            };
                            // 列宽自适应
                            let width = []
                            column.values.map((value) => {
                                if (!value) {
                                    width.push(10)
                                } else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
                                    width.push(parseFloat(value.toString().length * 2.15))
                                } else {
                                    width.push(parseFloat(value.toString().length * 1.15))
                                }
                            })
                            column.width = Math.max(...width)
    
                            // 行数据的样式
                            worksheet.getCell(`${column.letter}${index + 2}`).border = border
                        })
                    })
    
                    // 导出表格
                    workbook.xlsx.writeBuffer().then((buffer) => {
                        const blob = new Blob([buffer], {
                            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                        })
                        const link = document.createElement('a')
                        link.href = URL.createObjectURL(blob)
                        link.download = name + '.xlsx'
                        link.click()
                        URL.revokeObjectURL(link.href) // 下载完成释放掉blob对象
                    })
                }
            </script>
            <script src="https://cdn.jsdelivr.net/npm/exceljs@4.4.0"></script>
        </body>
    </html>
    

    回复
编辑
预览

报告相同问题?

问题事件

  • 修改了问题 2月5日
  • 创建了问题 2月4日
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部