导出今晚的菜谱图片

785 阅读1分钟

最近在做一个系统导出图片,然后到大屏上进行展示的功能。因为之前做了很多的excel模板导出、word模板导出,所以首先想到的是在网上找java实现模板导出的方案,百度之后发现一个貌似可行的方案:导出word->word转pdf->pdf转为png。这。。。好像有着亿丝丝的复杂,那么怎么简单的完成这个需求呢?

如果将需要导出的图片模板先用网页写出来,再把数据渲染上,最后将网页的部分区域截取为一张图片。

1. 核心知识点

  1. html2canvas,将网页区域转为canvas。
  2. canvas.toDataURL(),使用canvas的api转换为base64。
  3. 使用a标签将base64下载为具体的图片文件。

2. 效果展示

网页截图

image-20210923172504521

图片截图

image-20210923172604670

3. 具体步骤

1. 构建DOM模板

项目框架是使用的Vue,构建这么一个DOM模板还是很简单的。上代码

  <div style="margin-top: 10px">
      <a-empty v-if="!recipeData.list.length" />
      <div class="export-area" v-else>
        <!--        图片区域-->
        <div class="left"></div>
        <!--        数据区域-->
        <div class="main">
          <div class="title">
            <div class="time-interval">{{ recipeData.timeInterval_dictText }}</div>
            <div class="day">{{ recipeData.recipeDate_dictText }}</div>
          </div>
          <!--          不同类型的数据单独渲染-->
          <a-row class="recipe-area" v-for="key of ['other','3','6']" :key="key">
            <a-col :span="12" v-for="item of recipeMap[key]" :key="item.id">
              <div class="recipe-name">{{ item.dishName }}</div>
            </a-col>
          </a-row>
        </div>
      </div>
    </div>

2. 装载数据

发起Get请求获取到数据,然后对数据进行一系列的处理(例如今天周几等等),代码太长,就不贴上来了。

3. 导出图片

利用上面说到的相关知识点,完成图片的导出。代码如下

 handleExportImage() {
      if (this.recipeData.list.length > 0) {
        html2canvas(document.querySelector(".export-area")).then((canvas) => {
          //利用a标签的download属性,直接下载,避免上传服务器再下载
          let link = document.createElement("a");
          link.style.display = "none";
          link.href = canvas.toDataURL();
          link.setAttribute("download", `${this.model.recipeDate}_${this.recipeData.recipeDate_dictText}_${this.recipeData.timeInterval_dictText}图片`);
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link); //下载完成移除元素
        });
      } else {
        this.$message.warn("暂无数据!");
      }
    },

总结

因为之前做了很多的word、excel导入导出的影响、一看到导出的功能,思维就固化成后端使用模板导出来做了,结果前端做会更简单(后端我也没做,原谅我的妄言)。