整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

在Windows上,如何将 Excel 转换为 HTML?

想在网站上展示 Excel 数据时,将Excel 转换为 HTML 是最佳选择。Excel 非常适合组织数据,而 HTML 表格则非常适合网页。因此,我们将在本篇文章中讲解如何将 Excel 电子表格转换为 HTML 表格,此外,我们还将讨论具有内置人工智能功能的转换器工具。

第 1 部分:如何在 Windows 和 Mac 上将 Excel 转换为 HTML?

市面上有两种可以信赖的流行工具,包括 UPDF PDF 编辑器和 MS Excel,这两种工具都为 Windows 和 Mac 平台上的用户提供了有效的转换功能。我们在下面更详细地解释了这些工具。

方式 1. 通过 UPDF 将 Excel 导出为 HTML

UPDF是将 Excel 导出为 HTML 的首选,因为它非常可靠,不仅可以转换 PDF,还可以转换各种其他文件类型,包括 Excel 到 HTML。

UPDF 的突出功能之一是它能够保持原始文档的质量和格式。它甚至能够识别扫描文档, 即用OCR 功能将文档转换为可编辑文本。用它将 Excel 转换为 HTML 文件的步骤如下:

第1步:打开UPDF工具并创建PDF

首先,启动 UPDF 程序,然后,在左上角找到“文件”选项卡并单击它。然后,向下移动到“创建”选项并将光标置于打开“创建”选项。从列表中选择“从Excel 创建 PDF”,找到电子表格并将其打开。

第 2 步:导出转换后的电子表格并保存

导入 Excel 文件后它将转换为 PDF 格式。然后,前往右侧面板并点击“导出 PDF”按钮。接下来,从提供的列表中选择“HTML”,然后根据需要继续自定义“文档语言”、“页面范围”和文本识别设置。最后,按“导出”按钮将转换后的 HTML 文件存储在 Windows 或 Mac 上。

方式 2. 通过 Microsoft Excel 将 Excel 转换为HTML

使用 Microsoft Excel 将 Excel转换为 HTML 非常方便,只需几个简单的步骤,并且这个方法会保留电子表格的结构、格式和公式,其他人可以轻松查看数据并与之交互。请按照以下步骤进行简单的 Excel 到 HTML 转换:

第 1 步:使用 MS Excel 打开文件

首先,在 Windows 或 Mac 上浏览所需的电子表格,然后使用 MS Excel 打开它。接下来,点击 Excel 界面左上角的“文件”选项卡,从给定的选项中选择“另存为”,然后双击“此电脑”选项。

第 2 步:另存文件

上述步骤将打开“另存为”对话框,输入所需的“文件名”,然后从“另存为类型”下拉列表中选择“HTML”,然后点击对话框中的“保存”按钮。

第 2 部分:如何免费在线将 Excel 转换为 HTML?

这个方法可以很好地快速且高效地在线将 Excel 导出为 HTML,将用到Convertio 和 Zamzar 两个顶级的免费工具。

方式 1. 通过 Convertio 免费在线将 Excel 导出为 HTML

Convertio 是一个超级简单的在线工具,可以帮助转换不同类型的文件,可以轻松转换文档、图像、视频、音频文件和电子书,而且不需要下载或安装任何东西。让我们看一下在线将 Excel 转换为 HTML 的简单步骤:

第 1 步: 在网络浏览器中访问 Convertio 的网站

在顶部栏中查找“转换”选项并单击它,会出现具有扩展功能的菜单,从列表中选择“文档转换器”。

第 2 步: 导入 Excel 电子表格

有两种选择:使用文件资源管理器从电脑上传或直接从 Google Drive 或 Dropbox 导入。导入 Excel 文件后,找到“收件人”选项旁边的下拉菜单,单击它并从“文档”旁边的可用转换格式中选择“HTML”。

第 3 步: 选择所需的输出格式后,单击“转换”选项

单击后转换过程开始,完成后将看到“下载”按钮,只需单击它即可将转换后的 HTML 文件保存到电脑。

方法 2. 通过 Zamzar 在线将 Excel 转换为 HTML

Zamzar 是一款我强烈推荐的在线工具,它可以轻松地将 Excel 转换为HTML。由于其简约易上手的界面,Zamzar 是满足所有文件转换需求的首选,且这个软件无需注册就能使用。但它也存在一些限制,允许转换的最大文件大小为 2GB,支持最多 25 个文件批量转换。现在,让我们深入研究下面提到的将 Excel 转换为 HTML 的简单步骤:

第 1 步:打开计算机的网络浏览器并导航至 Zamzar 的网站

找到“选择文件”按钮并按下。然后,可以从计算机中选择所需的 Excel 文件。但是,将文件拖放到指定区域会更加方便。

第 2 步: Excel 文件成功上传后,选择输出格式

选择“HTML”作为转换格式,单击“立即转换”按钮,Zamzar 将开始转换过程。转换完成后,将出现“下载”按钮,单击它即可开始下载转换后的 HTML 文件。

第三部分:总结

这篇文章我们讲了几种工具来快速、轻松地将 Excel 转换为 HTML,几种工具对比下来,我们强烈推荐 UPDF 编辑器,它能够将 Excel 转换为 HTML,并提供强大的 AI 功能,让用户可以方便快捷地查查询自己想要的操作步骤。

需求场景

最近在开发项目时需要批量导入和导出Excel数据,在实现这个需求时,我们既可以在前端完成数据解析和文件生成工作,也可以通过前端发起导入以及导出请求后,后端实现解析文件流解析文件内容以及生成文件并提供下载链接的功能。

相较于后端处理Excel数据而言,使用前端导入导出可以提供更高的实时性,用户可以直接在浏览器中触发导出操作,无需等待后端处理。且可以在前端完成数据生成以及数据校验处理工作,大大减轻后端服务器的压力,大幅增强用户体验。

具体的技术方案选型主要看业务场景,如果对于小型数据集、实时性需求较高的导入导出操作,优先考虑前端实现。而对于大型数据集、需要业务逻辑处理、以及安全性要求高的场景,则后端处理更为合适。

技术方案

xlsx与xlsx-style组合方案:xlsx 是目前前端最常用的Excel解决方案,又叫做SheetJS,但社区版不支持修改Excel的样式,需要购买Pro版才可以,如果需要修改导出的Excel文件样式,需要结合xlsx-style库一起使用。但遗憾的是xlsx库已经两年多不更新,而xlsx-style上一个版本更是8年前发布,目前已经不再推荐使用该方案。

exceljs与file-saver方案:exceljs是一款免费开源支持导入导出Excel 操作工具,并且可以实现样式的修改以及 Excel 的高级功能,是非常值得推荐的一个处理 Excel 的库,file-saver可以实现保存文件到本地。本文以exceljs与file-saver操作xlsx格式文件为例介绍如何具体上手使用。

exceljs介绍

ExcelJS是一个用于在Node.js和浏览器中创建、读取和修改Excel文件的强大JavaScript库。它提供了丰富的功能和灵活的API,使你能够在你的应用程序中处理和操作Excel文件。

下面是一些ExcelJS库的关键特性和功能:

  1. 创建和修改Excel文件:ExcelJS允许你创建新的Excel工作簿,并在其中添加工作表、行和单元格。你可以设置单元格的值、样式、数据类型以及其他属性。
  2. 读取和解析Excel文件:ExcelJS支持读取和解析现有的Excel文件。你可以将Excel文件加载到工作簿中,然后访问工作表、行和单元格的数据。
  3. 导出和保存Excel文件:ExcelJS可以将工作簿保存为Excel文件,支持多种格式,如XLSX、XLS和CSV。你可以将工作簿保存到本地文件系统或将其发送到客户端以供下载。
  4. 处理复杂的Excel功能:ExcelJS支持处理复杂的Excel功能,如公式、图表、数据验证、条件格式和保护工作表等。你可以根据需要设置和操作这些功能。
  5. 支持自定义样式和格式:ExcelJS允许你自定义单元格、行、列和工作表的样式和格式。你可以设置字体、颜色、填充、边框、对齐方式以及数字和日期格式等。

参考文档

npm仓库地址:https://www.npmjs.com/package/exceljs

官方中文文档地址:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md

快速上手

安装依赖

exceljs用于Excel数据处理,file-sever用于保存到本地文件。

npm i exceljs
npm i file-saver

导出Excel

让我们先从简单的数据导出开始,快速体验如何使用exceljs导出Excel文件,需要注意的是在浏览器环境中运行 JavaScript,浏览器的安全策略通常不允许直接访问读写本地文件系统。在这种情况下,需要通过其他方式将文件转换为buffer数据,在导出Excel时使用FileSaver.js库将缓冲区数据保存到文件中。

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 175, "体重": 74},
    {"姓名": "李四", "年龄": 22, "身高": 177, "体重": 84},
    {"姓名": "王五", "年龄": 53, "身高": 155, "体重": 64}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}
</script>

<style scoped lang="scss">

</style>

当我们点击导出excel按钮时,调用exportFile函数,完成excel文件下载,下载后的文件内容如下:


导入Excel

导入excel文件时,同样使用FileReader的readAsArrayBuffer方法,将文件转换为二进制字符串,然后从buffer中加载数据并解析。

<template>
  <input
      type="file"
      accept=".xls,.xlsx"
      class="upload-file"
      @change="importExcel($event)"/>
</template>

<script setup>
import ExcelJS from "exceljs";
// 导出excel文件
const importExcel = (event) => {
  //获取选择的文件
  const files = event.target.files
  //创建Workbook实例
  const workbook = new ExcelJS.Workbook();
  // 使用FileReader对象来读取文件内容
  const fileReader = new FileReader()
  // 二进制字符串的形式加载文件
  fileReader.readAsArrayBuffer(files[0])
  fileReader.onload = ev => {
    console.log(ev)
    // 从 buffer中加载数据解析
    workbook.xlsx.load(ev.target.result).then(workbook => {
      // 获取第一个worksheet内容
      const worksheet = workbook.getWorksheet(1);
      // 获取第一行的标题
      const headers = [];
      worksheet.getRow(1).eachCell((cell) => {
        headers.push(cell.value);
      });
      console.log("headers", headers)
      // 创建一个空的JavaScript对象数组,用于存储解析后的数据
      const data = [];
      // 遍历工作表的每一行(从第二行开始,因为第一行通常是标题行)
      for (let rowNumber = 2; rowNumber <= worksheet.rowCount; rowNumber++) {
        const rowData = {};
        const row = worksheet.getRow(rowNumber);
        // 遍历当前行的每个单元格
        row.eachCell((cell, colNumber) => {
          // 获取标题对应的键,并将当前单元格的值存储到相应的属性名中
          rowData[headers[colNumber - 1]] = cell.value;
        });
        // 将当前行的数据对象添加到数组中
        data.push(rowData);
      }
      console.log("data", data)
    })
  }
}
</script>

<style scoped lang="scss">

</style>

上传文件后,解析内容如下所示:

进阶操作

添加数据

我们可以通过columns方法添加列标题并定义列键和宽度,设置好表头后,我们可以直接通过addRow方法,根据key值去添加每一行的数据。

参考文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E5%88%97

完整代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 添加表头列数据
  sheet1.columns = [
    {header: "姓名", key: "name", width: 20},
    {header: "年龄", key: "age", width: 10},
    {header: "身高", key: "height", width: 10},
    {header: "体重", key: "weight", width: 10},
  ];
  // 添加内容列数据
  sheet1.addRow({sort: 1, name: "张三", age: 18, height: 175, weight: 74});
  sheet1.addRow({sort: 2, name: "李四", age: 22, height: 177, weight: 88});
  sheet1.addRow({sort: 3, name: "王五", age: 53, height: 155, weight: 62});
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

添加数据后导出文件效果如下:

读取数据

我们可以使用getRow方法,传入指定行参数读取行数据。

使用getColumn方法,传入键、字母、id参数读取列数据。

使用eachCell方法可以遍历每个单元格内容。

参考文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E8%A1%8C

代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 添加表头列数据
  sheet1.columns = [
    {header: "姓名", key: "name", width: 20},
    {header: "年龄", key: "age", width: 10},
    {header: "身高", key: "height", width: 10},
    {header: "体重", key: "weight", width: 10},
  ];
  // 添加内容列数据
  sheet1.addRow({sort: 1, name: "张三", age: 18, height: 175, weight: 74});
  sheet1.addRow({sort: 2, name: "李四", age: 22, height: 177, weight: 88});
  sheet1.addRow({sort: 3, name: "王五", age: 53, height: 155, weight: 62});
  // 读取行数据
  sheet1.getRow(1).eachCell((cell, rowIdx) => {
    console.log("行数据", cell.value, rowIdx);
  });
  // 读取列数据,可以通过键(name),字母(B)和基于id(1)的列号访问单个列
  sheet1.getColumn("name").eachCell((cell, rowIdx) => {
    console.log("列数据", cell.value, rowIdx);
  });
}

</script>

<style scoped lang="scss">

</style>

效果

样式

在导出excel文件时,默认没有任何样式的,为了美观我们需要添加样式,而exceljs支持修改表格样式,具体内容可参考文档https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E6%A0%B7%E5%BC%8F

例如,我们需要设置所有单元格居中对齐,并添加边框。并分别指定标题行和内容行字体大小、背景颜色、行高属性,代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 175, "体重": 74},
    {"姓名": "李四", "年龄": 22, "身高": 177, "体重": 84},
    {"姓名": "王五", "年龄": 53, "身高": 155, "体重": 64}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 修改所有单元格样式
  // 遍历每一行
  sheet1.eachRow((row, rowNumber) => {
    // 遍历每个单元格
    row.eachCell((cell) => {
      // 设置边框样式
      cell.border = {
        top: {style: 'thin'},
        left: {style: 'thin'},
        bottom: {style: 'thin'},
        right: {style: 'thin'}
      };
      // 设置居中对齐
      cell.alignment = {
        vertical: 'middle',
        horizontal: 'center'
      };
    });
  });
  // 获取标题行数据
  const titleCell = sheet1.getRow(1);
  // 设置行高为30
  titleCell.height = 30
  // 设置标题行单元格样式
  titleCell.eachCell((cell) => {
    // 设置标题行背景颜色为黄色
    cell.fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: {argb: 'FFFF00'}
    };
    // 设置标题行字体
    cell.font = {
      color: {argb: 'FF0000'}, //颜色为红色
      bold: true,// 字体粗体
      size: 18 // 设置字体大小为18
    };
  })
  // 获取第二行到最后一行的内容数据
  const bodyRows = sheet1.getRows(2, sheet1.rowCount);
  // 处理内容行的数据
  bodyRows.forEach((bodyRow) => {
    // 设置行高为20
    bodyRow.height = 20
    bodyRow.eachCell((cell) => {
      cell.font = {
        size: 16 // 设置内容行字体大小为16
      };
    });
  });
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

导出Excel样式效果如下所示,已经成功按我们指定的样式导出了文件:

筛选

在很多的时候我们需要对表格中每一列的数据进行筛选,比如直接筛选姓名等列信息,我们可以通过 autoFilter 来添加筛选。参考文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E8%87%AA%E5%8A%A8%E7%AD%9B%E9%80%89%E5%99%A8

代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 175, "体重": 74},
    {"姓名": "李四", "年龄": 22, "身高": 177, "体重": 84},
    {"姓名": "王五", "年龄": 53, "身高": 155, "体重": 64}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 单列筛选
  // sheet1.autoFilter = "A1";
  // 多个列筛选
  sheet1.autoFilter = "A1:C1";
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

导入后的效果如下,在姓名、年龄、身高列添加了筛选按钮:

公式值

参考文档:exceljs/README_zh.md at 5bed18b45e824f409b08456b59b87430ded023ab · exceljs/exceljs · GitHub

我们可以直接对表格中的数据进行公式计算,比如 求和(SUM)平均数(AVERAGE) 等。

例如我们需要计算平均值、最大值、指定公式时,代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 1.75, "体重": 74},
    {"姓名": "李四", "年龄": 22, "身高": 1.77, "体重": 84},
    {"姓名": "王五", "年龄": 53, "身高": 1.55, "体重": 64}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 添加单元格
  sheet1.getCell("E1").value = "BMI指数";
  sheet1.getCell("F1").value = "平均身高";
  sheet1.getCell("G1").value = "最大体重";
  // 计算平均身高
  sheet1.getCell("F2").value = {formula: "=AVERAGE(C2:C4)"};
  // 计算最大体重
  sheet1.getCell("G2").value = {formula: "=MAX(D2:D4)"};
  // 计算BMI指数
  // 获取第5列对象
  const BMIRange = sheet1.getColumn(5)
  BMIRange.eachCell((cell) => {
    console.log("cell", cell)
    console.log(cell.row)
    // 从第二列开始添加计算公式
    if (cell.row >= 2) {
      sheet1.getCell("E" + cell.row).value = {formula: "D" + cell.row + "/" + "(C" + cell.row + "*" + "C" + cell.row + ")"};
    }
  })
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

导出Excel文件效果如下,E列已经自动替换为公式计算。

合并单元格

表格的合并应该是业务需求中最频繁的功能。当然这一功能使用 xlsx 也可以实现,我们只需要使用mergeCells方法,传入合并单元格范围参数即可。

参考文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC

具体代码实现如下所示:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 175, "体重": 74},
    {"姓名": "李四", "年龄": 18, "身高": '未知', "体重": '未知'},
    {"姓名": "王五", "年龄": 53, "身高": '未知', "体重": '未知'},
    {"姓名": "赵六", "年龄": 12, "身高": '未知', "体重": '未知'}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 上下合并单元格
  sheet1.mergeCells("B2:B3");
  // 左右合并单元格
  sheet1.mergeCells("C3:D3");
  // 范围合并单元格
  sheet1.mergeCells("C4:D5");
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

单元格合并后导出文件效果如下:

数据验证

有时候我们需要为某个单元格添加数据可以方便直接下拉选择指定的值,此时就需要使用数据验证功能,传入可填写的选项列表。

参考文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E6%95%B0%E6%8D%AE%E9%AA%8C%E8%AF%81

例如我们对是否注册列添加数据验证,可填值为"是、否、未知",具体代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 1.75, "体重": 74, "是否注册": ''},
    {"姓名": "李四", "年龄": 22, "身高": 1.77, "体重": 84, "是否注册": ''},
    {"姓名": "王五", "年龄": 53, "身高": 1.55, "体重": 64, "是否注册": ''}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 获取第5列对象
  const VerificationRange = sheet1.getColumn(5)
  VerificationRange.eachCell((cell) => {
    // 从第二列开始添加数据验证规则
    if (cell.row >= 2) {
      sheet1.getCell("E" + cell.row).dataValidation = {
        type: "list",
        allowBlank: true,
        formulae: ['"是,否,未知"']
      };
    }
  })
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

导出的excel文件效果如下:

条件格式化

我们可以为指定单元格添加条件格式,对满足条件的单元格设置指定的样式。

参考文档:exceljs/README_zh.md at 5bed18b45e824f409b08456b59b87430ded023ab · exceljs/exceljs · GitHub

例如为年龄大于18岁单元格进行红色标注,代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
</template>

<script setup>
import ExcelJS from "exceljs";
import FileSaver from "file-saver";
// 导出excel文件
const exportExcel = () => {
  // 创建工作簿
  const workbook = new ExcelJS.Workbook();
  // 添加工作表,名为sheet1
  const sheet1 = workbook.addWorksheet("sheet1");
  // 导出数据列表
  const data = [
    {"姓名": "张三", "年龄": 18, "身高": 1.75, "体重": 74},
    {"姓名": "李四", "年龄": 22, "身高": 1.77, "体重": 84},
    {"姓名": "王五", "年龄": 53, "身高": 1.55, "体重": 64}
  ]
  // 获取表头所有键
  const headers = Object.keys(data[0])
  // 将标题写入第一行
  sheet1.addRow(headers);
  // 将数据写入工作表
  data.forEach((row) => {
    const values = Object.values(row)
    sheet1.addRow(values);
  });
  // 年龄大于18岁红色标注
  sheet1.addConditionalFormatting({
    ref: "B2:B4",
    rules: [
      {
        type: "cellIs",
        operator: "greaterThan",
        priority: 1,
        formulae: [18],
        style: {
          fill: {
            type: "pattern",
            pattern: "solid",
            bgColor: { argb: "FFFFC0CB" },
          },
        },
      },
    ],
  });
  // 导出表格文件
  workbook.xlsx.writeBuffer().then((buffer) => {
    let file = new Blob([buffer], {type: "application/octet-stream"});
    FileSaver.saveAs(file, "ExcelJS.xlsx");
  }).catch(error => console.log('Error writing excel export', error))
}

</script>

<style scoped lang="scss">

</style>

导出后的文件效果如下:

封装exceljs

封装导入导出函数

为了提高项目代码的复用性,通常会将excel导入导出功能封装到单独的函数中方便调用,封装后的函数如下:

import ExcelJS from "exceljs";
import FileSaver from "file-saver";
import {timeFile} from "@/utils/timeFormat";
// 导出excel文件
export function exportFile(export_data, filename) {
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    // 添加工作表,名为sheet1
    const sheet1 = workbook.addWorksheet("sheet1");
    // 获取表头所有键
    const headers = Object.keys(export_data[0])
    // 将标题写入第一行
    sheet1.addRow(headers);
    // 将数据写入工作表
    export_data.forEach((row) => {
        const values = Object.values(row)
        sheet1.addRow(values);
    });
    // 设置默认宽高属性
    sheet1.properties.defaultColWidth = 20
    sheet1.properties.defaultRowHeight = 20
    // 修改所有单元格样式
    // 遍历每一行
    sheet1.eachRow((row, rowNumber) => {
        // 遍历每个单元格
        row.eachCell((cell) => {
            // 设置边框样式
            cell.border = {
                top: {style: 'thin'},
                left: {style: 'thin'},
                bottom: {style: 'thin'},
                right: {style: 'thin'}
            };
            // 设置居中对齐
            cell.alignment = {
                vertical: 'middle',
                horizontal: 'center'
            };
        });
    });
    // 获取标题行数据
    const titleCell = sheet1.getRow(1);
    // 设置标题行单元格样式
    titleCell.eachCell((cell) => {
        // 设置标题行背景颜色
        cell.fill = {
            type: 'pattern',
            pattern: 'solid',
            fgColor: {argb: '3498db'}
        };
        // 设置标题行字体
        cell.font = {
            bold: true,// 字体粗体
        };
    })
    // 导出表格文件
    workbook.xlsx.writeBuffer().then((buffer) => {
        let file = new Blob([buffer], {type: "application/octet-stream"});
        FileSaver.saveAs(file, filename + timeFile() + ".xlsx");
    }).catch(error => console.log('Error writing excel export', error))
}

// 导入excel文件
export function importFile(content) {
    return new Promise((resolve, reject) => {
        // 创建一个空的JavaScript对象数组,用于存储解析后的数据
        const data = [];
        //创建Workbook实例
        const workbook = new ExcelJS.Workbook();
        workbook.xlsx.load(content).then(workbook => {
            // 获取第一个worksheet内容
            const worksheet = workbook.getWorksheet(1);
            // 获取第一行的标题
            const headers = [];
            worksheet.getRow(1).eachCell((cell) => {
                headers.push(cell.value);
            });
            // console.log("headers", headers)
            // 遍历工作表的每一行(从第二行开始,因为第一行通常是标题行)
            for (let rowNumber = 2; rowNumber <= worksheet.rowCount; rowNumber++) {
                const rowData = {};
                const row = worksheet.getRow(rowNumber);
                // 遍历当前行的每个单元格
                row.eachCell((cell, colNumber) => {
                    // 获取标题对应的键,并将当前单元格的值存储到相应的属性名中
                    rowData[headers[colNumber - 1]] = cell.value;
                });
                // 将当前行的数据对象添加到数组中
                data.push(rowData);
            }
            // console.log("data", data)
            resolve(data);
        }).catch(error => {
            reject(error);
        });
    })
}

vue组件调用

以element plus为例,调用函数完成Excel文件导入与导出,代码如下:

<template>
  <el-button type="primary" @click="exportExcel">导出excel</el-button>
  <el-button type="success" @click="importExcel">导入excel</el-button>
  <p>导入数据预览</p>
  {{ uploadData}}
  <el-dialog
      v-model="uploadDialogVisible"
      title="批量添加数据"
      width="40%"
  >
    <el-form label-width="120px">
      <el-form-item label="模板下载:">
        <el-button type="info" @click="downloadTemplate">
          <el-icon>
            <Download/>
          </el-icon>
          点击下载
        </el-button>
      </el-form-item>
      <el-form-item label="文件上传:">
        <el-upload drag accept=".xls,.xlsx" :auto-upload="false" :on-change="handleChange">
          <el-icon class="el-icon--upload">
            <upload-filled/>
          </el-icon>
          <div class="el-upload__text">
            将文件拖到此处,或<em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">
              请上传.xls,.xlsx格式文件,文件最大为500kb
            </div>
          </template>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitUpload">
          导入
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import {ref} from "vue";
import {ElMessage} from "element-plus";
import {Download, UploadFilled} from "@element-plus/icons-vue"
import {getDemo} from "@/api/home";
import {timeFormatConversion} from "@/utils/timeFormat";
import {exportFile, importFile} from "@/utils/excel";
// 表格字段配置
const fieldConfig = ref([
  {
    'label': 'ID', // 标签
    'model': 'id',// 字段名
    'is_export': true,// 是否导出该字段
  },
  {
    'label': '用户名', // 标签
    'model': 'username',// 字段名
    'is_export': true, // 是否导出该字段
  },
  {
    'label': '省份', // 标签
    'model': 'province',// 字段名
    'is_export': true // 是否导出该字段
  },
  {
    'label': '性别', // 标签
    'model': 'sex_name',// 字段名
    'is_export': true // 是否导出该字段
  },
  {
    'label': '生日', // 标签
    'model': 'birthday',// 字段名
    'is_export': true, // 是否导出该字段
  },
  {
    'label': '身高(cm)', // 标签
    'model': 'height',// 字段名
    'is_export': true, // 是否导出该字段
  },
  {
    'label': '体重(kg)', // 标签
    'model': 'weight',// 字段名
    'is_export': true,// 是否导出该字段
  },
  {
    'label': '注册时间', // 标签
    'model': 'created_time',// 字段名
    'is_export': true, // 是否导出该字段
  },
  {
    'label': '个人介绍', // 标签
    'model': 'introduction',// 字段名
    'is_export': true,// 是否导出该字段
  }
])
// 导出Excel事件
const exportExcel = () => {
  ElMessage({
    message: '开始导出数据,请稍候!',
    type: 'success',
  })
  // 导出数据查询参数
  const printParams = {
    'size': 1000,
    'page': 1,
  }
  // 获取需要导出的字段配置
  const export_fields = fieldConfig.value
      .filter(obj => obj['is_export'])
      .map(({label, model}) => ({[model]: label}))
  // 处理数据结构
  getDemo(printParams).then((response) => {
    // console.log(response.results)
    const export_data = response.results.map(obj => {
      const newObj = {};
      export_fields.forEach(field => {
        const [key, value] = Object.entries(field)[0];
        if (key === 'created_time') {
          newObj[value] = timeFormatConversion((obj[key]), 'YYYY-MM-DD HH:mm:ss');
        } else {
          newObj[value] = obj[key];
        }
      });
      return newObj;
    });
    let filename = '示例用户'
    exportFile(export_data, filename);
  }).catch(response => {
    //发生错误时执行的代码
    console.log(response)
    ElMessage.error('获取列表数据失败!')
  });
}
// 导入excel弹窗是否显示
const uploadDialogVisible = ref(false)
// 点击导入excel按钮事件
const importExcel = () => {
  uploadDialogVisible.value = true
}
// 下载模板文件
const downloadTemplate = () => {
  window.open('https://api.cuiliangblog.cn/static/demo-template.xlsx')
}
// 文件数据
const uploadData=ref([])
// 文件上传事件
const handleChange = (file) => {
  const reader = new FileReader();
  reader.onload = () => {
    const content = reader.result;
    importFile(content).then((data) => {
      console.log(data)
      uploadData.value = data
    }).catch(response => {
      //发生错误时执行的代码
      console.log(response)
      ElMessage.error('获取列表数据失败!')
    });
  };
  reader.readAsBinaryString(file.raw);
};
// 点击导入excel提交数据事件
const submitUpload = () => {
  uploadDialogVisible.value =false
}
</script>

<style scoped lang="scss">

</style>

页面效果

封装后的页面效果如下,至此,一个简单的vue前端实现Excel文件导入导出功能便开发完成了。

完整代码

gitee:https://gitee.com/cuiliang0302/vue3_vite_element-plus

github:https://github.com/cuiliang0302/vue3-vite-template

查看更多

微信公众号

微信公众号同步更新,欢迎关注微信公众号《崔亮的博客》第一时间获取最近文章。

博客网站

崔亮的博客-专注devops自动化运维,传播优秀it运维技术文章。更多原创运维开发相关文章,欢迎访问https://www.cuiliangblog.cn

自动化##Python#

遇到的需求是这样的,需要频繁将htm类型的数据转为Excel表格,这是一个重复性的工作,极大程度上浪费时间和人力,所以我找到了一个解决方案。用Python开发一个桌面的自动化的小工具,虽然实现起来简单,但是真心好用。今天特意写篇文章分享给大家。希望你从获得的是这个思路,里面的功能你可以换成你工作中重复的工作。

一、背景介绍

首先 htm 数据是如下这样的,一个网址。内容在网页中,这里需要写爬虫,获取网页中的信息,自动保存到excel ,并输出excel格式的文件。

1、需求结果

2、解析htm里的内容,并保存到excel

from bs4 import BeautifulSoup
import pandas as pd


class htmToExcel(object):
    def __init__(self, file_name, file_path):
        self.file_name = file_name
        self.file_path = file_path


    def htm_to_excel(self):
        print(self.file_path)
        soup = BeautifulSoup(open(self.file_path), features='html.parser')
        table = soup.find("table")
        tr_list = table.find_all("tr")
        th = tr_list.pop(0)
        title = th.find_all("th")
        lis = []
        for tr in tr_list:
            data = {}
            td = tr.find_all("td")
            for i in range(len(td)):
                data[title[i].text] = td[i].text
            lis.append(data)
        df = pd.DataFrame(lis)
        df.to_excel('{}.xlsx'.format(str(self.file_name).split('.')[0]), index=False)
        return '转换成功!'




if __name__ == '__main__':
    file_name = input("请输入文件名字:")
    path = 'C:/Users/cherich/Desktop/' + file_name
    pross = htmToExcel(file_name, path)
    print(pross.htm_to_excel())

二、设计窗口

创建桌面窗口,这里使用tkinter,它是Python 自带的gui库,安装后即可使用。

1、安装命令:

pip install tkinter

2、利用tkinter完成可视化窗口上传文件功能:

from tkinter import Tk, Entry, Button, mainloop
import tkinter.filedialog
import htm_to_excel
from tkinter import messagebox



def Upload():
    try:
        selectFileName = tkinter.filedialog.askopenfilename(title='选择文件')
        pross = htm_to_excel.htmToExcel(str(selectFileName).split('/')[-1], selectFileName)
        pross.htm_to_excel()
        messagebox.showinfo('Info', '转换成功!')
        root.destroy()
    except Exception as e:
        print(e)
        messagebox.showinfo('Info', '转换失败!')




root = Tk()
root.title('HTM转Excel小工具')
root.geometry('+500+300')


e1 = Entry(root, width=50)
e1.grid(row=0, column=0)
btn1 = Button(root, text=' 上传 ', command=Upload).grid(row=1, column=0, pady=5)
mainloop()

三、打包exe

本功能打包成exe的好处是不需要将代码部署到服务器,直接将打包好的exe发给对方,就能直接使用。对于这种小而轻的功能非常友好。

1、安装命令:

pip install pyinstaller

2、 打开DOS窗口并切换到demo.py文件的目录,注意路径不要有中文:





在当前目录下,会生成两个文件夹:build和dist。dist里面就是所有可执行exe文件,发送快捷方式到桌面,点击demo.exe就能运行了。

3、pyinstaller指令的常见可选参数:

-i 给应用程序添加图标
-F 指定打包后只生成一个exe格式的文件
-D –onedir 创建一个目录,包含exe文件,但会依赖很多文件(默认选项)
-c –console, –nowindowed 使用控制台,无界面(默认)
-w –windowed, –noconsole 使用窗口,无控制台
-p 添加搜索路径

四、该注意的坑!

如果生成exe之后,你发现你的程序异常的慢,请检查你的导包代码,尽量不要出现 from ··· import * ,否则每次启动程序,都会导入大量函数占用大量时间,亲测有效。


今天的文章写到这里,如果你觉得对你有帮助,欢迎点赞哦~