实现将html页面导出word (.docx)

参考:

方式一:html-docx-js库实现

js 复制代码
"file-saver": "^2.0.5",
"html-docx-js": "^0.3.1",
js 复制代码
import htmlDocx from 'html-docx-js/dist/html-docx';
import saveAs from 'file-saver';
export default {
  methods: {
    exportClick() {
      var content = ` <h1>This is an about page</h1>
      <h2>This is an about page</h2>`;
      var page = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body>' + content + '</body></html>';
      var converted = htmlDocx.asBlob(page);
      // 用 FielSaver.js里的保存方法 进行输出
      saveAs(converted, 'test.docx');
    }
  }
};

方式二:docx库实现将html页面导出word

  • 在JavaScript中使用docx库来创建和操作Word文档,并使用file-saver库来保存生成的文档文件。导入的类和函数将用于构建文档的结构和内容,而saveAs函数则用于将最终的文档保存到用户的设备上。
  • 与之前的html-docx-js不同,docx库提供了更精细的文档控制能力。
json 复制代码
 "docx": "^9.5.1"
 "file-saver": "^2.0.5",

docx官网:docx.js.org/#/

js 复制代码
import { Document, Packer, Paragraph, TextRun, ImageRun, Table, TableCell, TableRow, WidthType, VerticalAlign, AlignmentType } from 'docx';
import { saveAs } from 'file-saver';

这里导入的类和类型包括:

  • Document: 用于创建一个新的Word文档。
  • Packer: 用于将文档打包成一个可以保存的文件。
  • Paragraph: 用于创建文档中的段落。
  • TextRun: 用于在段落中添加文本。
  • ImageRun: 用于在文档中插入图片。
  • Table: 用于创建表格。
  • TableCell: 用于创建表格中的单元格。
  • TableRow: 用于创建表格中的行。
  • WidthType: 用于设置表格或单元格的宽度类型。
  • VerticalAlign: 用于设置垂直对齐方式。
  • AlignmentType: 用于设置文本的对齐方式。

这一行从名为file-saver的模块中导入了一个名为saveAs的函数。file-saver是一个用于在浏览器中保存文件的库,saveAs函数可以用来将文件保存到用户的本地文件系统。

eg:(1)

js 复制代码
import { Document, Packer, Paragraph, TextRun, ImageRun, Table, TableCell, TableRow, WidthType, VerticalAlign, AlignmentType } from 'docx';
import { saveAs } from 'file-saver';

// 假设这是你要导出的HTML内容
const htmlContent = `
  <h1>Sample Document</h1>
  <p>This is a sample paragraph.</p>
  <img src="https://via.placeholder.com/150" alt="Sample Image">
  <table>
    <tr>
      <td>Row 1, Cell 1</td>
      <td>Row 1, Cell 2</td>
    </tr>
    <tr>
      <td>Row 2, Cell 1</td>
      <td>Row 2, Cell 2</td>
    </tr>
  </table>
`;

// 解析HTML内容
const parser = new DOMParser();
const doc = parser.parseFromString(htmlContent, 'text/html');

// 创建一个新的Word文档
const docxDoc = new Document();

// 处理标题
const h1Elements = doc.getElementsByTagName('h1');
for (let i = 0; i < h1Elements.length; i++) {
  const h1Text = h1Elements[i].textContent;
  docxDoc.addSection({
    properties: {},
    children: [
      new Paragraph({
        text: h1Text,
        heading: 'Heading1',
      }),
    ],
  });
}

// 处理段落
const pElements = doc.getElementsByTagName('p');
for (let i = 0; i < pElements.length; i++) {
  const pText = pElements[i].textContent;
  docxDoc.addSection({
    properties: {},
    children: [
      new Paragraph({
        text: pText,
      }),
    ],
  });
}

// 处理图片
const imgElements = doc.getElementsByTagName('img');
for (let i = 0; i < imgElements.length; i++) {
  const imgSrc = imgElements[i].src;
  const imgAlt = imgElements[i].alt;
  const imgBuffer = await fetch(imgSrc).then(res => res.arrayBuffer());

  docxDoc.addSection({
    properties: {},
    children: [
      new Paragraph({
        children: [
          new ImageRun({
            data: Buffer.from(imgBuffer),
            transformation: {
              width: 1000000,
              height: 1000000,
            },
          }),
        ],
      }),
    ],
  });
}

// 处理表格
const tableElements = doc.getElementsByTagName('table');
for (let i = 0; i < tableElements.length; i++) {
  const table = tableElements[i];
  const rows = table.getElementsByTagName('tr');
  const docxTable = new Table({
    rows: Array.from(rows).map(row => {
      const cells = row.getElementsByTagName('td');
      return new TableRow({
        children: Array.from(cells).map(cell => {
          return new TableCell({
            children: [
              new Paragraph({
                text: cell.textContent,
              }),
            ],
          });
        }),
      });
    }),
  });

  docxDoc.addSection({
    properties: {},
    children: [docxTable],
  });
}

// 将文档打包并保存为Word文件
Packer.toBlob(docxDoc).then(blob => {
  saveAs(blob, 'sample-document.docx');
  console.log('Document created successfully');
});

eg:(2)

js 复制代码
import { Document, Packer, Paragraph, TextRun, Table, TableCell, TableRow, WidthType, VerticalAlign, AlignmentType, Shading } from 'docx';
import { saveAs } from 'file-saver';

// 创建一个新的Word文档
const doc = new Document();

// 创建一个表格
const table = new Table({
  rows: [
    new TableRow({
      cells: [
        new TableCell({
          children: [new Paragraph("Cell 1")],
          shading: { fill: "FFFFFF", themeFill: "background1", themeFillShade: "80" }, // 设置单元格背景色为白色并调整透明度
        }),
        new TableCell({
          children: [new Paragraph("Cell 2")],
          shading: { fill: "FFFFFF", themeFill: "background1", themeFillShade: "80" }, // 设置单元格背景色为白色并调整透明度
        }),
      ],
    }),
    new TableRow({
      cells: [
        new TableCell({
          children: [new Paragraph("Cell 3")],
          shading: { fill: "FFFFFF", themeFill: "background1", themeFillShade: "80" }, // 设置单元格背景色为白色并调整透明度
        }),
        new TableCell({
          children: [new Paragraph("Cell 4")],
          shading: { fill: "FFFFFF", themeFill: "background1", themeFillShade: "80" }, // 设置单元格背景色为白色并调整透明度
        }),
      ],
    }),
  ],
});

// 将表格添加到文档中
doc.addSection({
  properties: {},
  children: [table],
});

// 将文档打包并保存为Word文件
Packer.toBlob(doc).then(blob => {
  saveAs(blob, 'sample-document.docx');
  console.log('Document created successfully');
});

更多样式设置

js 复制代码
const table = new Table({
  rows: [
    new TableRow({
      cells: [
        new TableCell({
          children: [new Paragraph("Cell 1")],
          shading: { fill: "FF0000" }, // 设置单元格背景色为红色
          properties: {
            borders: {
              top: { color: "000000", size: 12, space: 0, type: "single" },
              bottom: { color: "000000", size: 12, space: 0, type: "single" },
              left: { color: "000000", size: 12, space: 0, type: "single" },
              right: { color: "000000", size: 12, space: 0, type: "single" },
            },
            verticalAlignment: VerticalAlign.CENTER, // 设置单元格垂直对齐方式为居中
          },
        }),
        new TableCell({
          children: [new Paragraph("Cell 2")],
          shading: { fill: "00FF00" }, // 设置单元格背景色为绿色
          properties: {
            borders: {
              top: { color: "000000", size: 12, space: 0, type: "single" },
              bottom: { color: "000000", size: 12, space: 0, type: "single" },
              left: { color: "000000", size: 12, space: 0, type: "single" },
              right: { color: "000000", size: 12, space: 0, type: "single" },
            },
            verticalAlignment: VerticalAlign.CENTER, // 设置单元格垂直对齐方式为居中
          },
        }),
      ],
    }),
    // 其他行...
  ],
  properties: {
    alignment: AlignmentType.CENTER, // 设置表格水平对齐方式为居中
  },
});
相关推荐
Dragon Wu44 分钟前
前端 下载后端返回的二进制excel数据
前端·javascript·html5
北海几经夏1 小时前
React响应式链路
前端·react.js
晴空雨1 小时前
React Media 深度解析:从使用到 window.matchMedia API 详解
前端·react.js
一个有故事的男同学1 小时前
React性能优化全景图:从问题发现到解决方案
前端
探码科技1 小时前
2025年20+超实用技术文档工具清单推荐
前端
Juchecar1 小时前
Vue 3 推荐选择组合式 API 风格(附录与选项式的代码对比)
前端·vue.js
uncleTom6661 小时前
# 从零实现一个Vue 3通用建议选择器组件:设计思路与最佳实践
前端·vue.js
影i1 小时前
iOS WebView 异步跳转解决方案
前端
Nicholas681 小时前
flutter滚动视图之ScrollController源码解析(三)
前端
爪洼守门员1 小时前
安装electron报错的解决方法
前端·javascript·electron