在xlsx模块, SheetJS 居中

  • Post author:
  • Post category:其他


想要SheetJS 居中的时候踩了一下午的坑。



1. 导不出样式的代码

import FileSaver from 'file-saver'
import XLSX from 'xlsx'   // https://sheetjs.com


var ws = XLSX.utils.table_to_sheet(targetEl)
var wb = XLSX.utils.book_new();
var range = XLSX.utils.decode_range(ws['!ref'])

// .. 省略业务逻辑部分
let headerRow = [0,1]  

    if(headerRow){  // 头部样式
      // 定义样式
      var headerStyle = {
        font: { bold: true },
        alignment: { horizontal: 'center' }
      };
      // 设置行的样式
      for (const rowIdx of headerRow) {
        for (var col = range.s.c; col <= range.e.c; col++) {
          var cell = ws[XLSX.utils.encode_cell({ r: rowIdx, c: col })];
          cell.s = headerStyle;
          cell.v = cell.v;
          cell.t = 's'; // 强制将单元格类型设置为字符串
        }
      } 
    }

var writingOpt = { 
  bookType: 'xlsx',
  bookSST: true,
  type: 'array'
}
var wbout = XLSX.write(wb, writingOpt)
FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), exportName)



2. 需要有两个地方要改

Q1. 首先保存的时候

type

要改成

binary

方式

Q2. 保存的时候需要使用

xlsx-style

模块



3. 开始挖呀挖呀挖



A1. 使用

binary

方式保存

var writingOpt = { 
  bookType: 'xlsx',
  bookSST: true,
  type: 'binary'    // <--- 1.改这里
}


/* 
2.  type:'array'改为'binary' 后因为下面代码会报错, 打不开excel
new Blob([wbout], { type: 'application/octet-stream' }
要文本转换成数组缓存后再生成二进制对象
*/

// 添加String To ArrayBuffer
function s2ab(s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i < s.length; i++) {
    view[i] = s.charCodeAt(i) & 0xFF;
  }
  return buf;
} 

let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })

FileSaver.saveAs(blob, exportName)

代码改完试一下,可以下载了。

但依然样式没起作用

要是下载不了,打开不了那可能是其他问题了。



A2. 使用

xlsx-style

模块生成文件
  1. 首先安装模块
npm install xlsx-style 

在项目里安装报好多错误直接强制安装,不检查依赖。

npm install xlsx-style -force

然后确认 package.json 是否安装完成,然后重启一下服务

// package.json
  "dependencies": {
// ...其他省略
    "xlsx": "^0.17.3",
    "xlsx-style": "^0.8.13"
  }
  1. 安装完成后 找不到

    cptable

    模块会报错

    报错内容如下:
./node_modules/xlsx-style/dist/cpexcel.js Module not found: Error: Can't resolve './cptable' in 

这个问题在

vue.config.js

里配置一下就可以解决。

其他框架自己找找方法,反正只要不让他报错能启动就行。

module.exports = {
//  ...其他配置省略
  configureWebpack: { 
//  ...其他配置省略
    externals:{
      './cptable':'var cptable'
    },
  },
  1. 安装完

    xlsx-style

    后改代码
import XLSX2 from "xlsx-style";    // 1. 引入模块

// 2. 使用`xlsx-style` 生成。 XLSX.write => XLSX2.write
var wbout = XLSX2.write(wb, writingOpt)



4. 最终代码

import FileSaver from 'file-saver'
import XLSX from 'xlsx'   // https://sheetjs.com
import XlsxStyle from "xlsx-style";


var ws = XLSX.utils.table_to_sheet(targetEl)
var wb = XLSX.utils.book_new();
var range = XLSX.utils.decode_range(ws['!ref'])

// .. 省略业务逻辑部分
let headerRow = [0,1]  

    if(headerRow){  // 头部样式
      // 定义样式
      var headerStyle = {
        font: { bold: true },
        alignment: { horizontal: 'center' }
      };
      // 设置行的样式
      for (const rowIdx of headerRow) {
        for (var col = range.s.c; col <= range.e.c; col++) {
          var cell = ws[XLSX.utils.encode_cell({ r: rowIdx, c: col })];
          cell.s = headerStyle;
          cell.v = cell.v;
          cell.t = 's'; // 强制将单元格类型设置为字符串
        }
      } 
    }

var writingOpt = { 
  bookType: 'xlsx',
  bookSST: true,
  type: 'binary'
}
var wbout = XlsxStyle.write(wb, writingOpt)

// String To ArrayBuffer
function s2ab(s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i < s.length; i++) {
    view[i] = s.charCodeAt(i) & 0xFF;
  }
  return buf;
} 

let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })

FileSaver.saveAs(blob, exportName) 

在小小的坑里🎶

挖呀挖呀挖🎵

种小小的霸个 🎶

背小小的锅 🎵

完事,下班!

PS:样式配置参考, 没试过。 应该没啥问题吧 😃

/*
1. `font`:设置的是字体方面的样式
2. font>>> sz:设置的是字号
3. font>>>bold:字体加粗
4. alignment:设置单元格的居中及自动换行
5. alignment>>>horizontal:水平是否居中
6. alignment>>>vertical:竖直是否居中
7. alignment>>>wrapText:是否换行展示内容
8. fill:设置单元格的背景色等
9. fill>>>fgColor:设置背景色
*/
let cellStyle = {
  font: {
    sz: 20, //设置标题的字号
    bold: true, //设置标题是否加粗
  },
  alignment: {
    horizontal: 'center', 
    vertical: 'center', 
    wrapText: true 
  }, //设置标题水平竖直方向居中,并自动换行展示
  fill: {
    fgColor: { 
      rgb: 'ebebeb' 
    }  //设置标题单元格的背景颜色
  }
}; 



版权声明:本文为qlynick原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。