|
@@ -7,14 +7,26 @@
|
|
|
top="10vh"
|
|
|
:before-close="handleClose"
|
|
|
class="dialog_diy"
|
|
|
+ ref="docxTemplateDialogRef"
|
|
|
>
|
|
|
<div class="box" v-loading="loading">
|
|
|
- <div class="b_left">
|
|
|
- <topicVue :cJson="checkJson" :checktype="2" :see="true" :isTeacher="1" title="" brief="" ref="topicVue"/>
|
|
|
- </div>
|
|
|
+ <div
|
|
|
+ class="b_left"
|
|
|
+ v-loading="wordContentLoading"
|
|
|
+ ref="wordAreaRef"
|
|
|
+ contenteditable="true"
|
|
|
+ >
|
|
|
+ <VueOfficeDocx
|
|
|
+ ref="vueOfficeDocxRef"
|
|
|
+ v-if="downFileData && !downFileData.txtUrl"
|
|
|
+ :src="downFileData ? downFileData.url : ''"
|
|
|
+ />
|
|
|
+
|
|
|
+ <txtHtmlView ref="txtHtmlViewRef" v-if="downFileData && downFileData.txtUrl" :url="downFileData.txtUrl" @getTxtContent="getTxtContent"/>
|
|
|
+ </div>
|
|
|
<div class="b_right">
|
|
|
<div class="d_box">
|
|
|
- <div class="d_b_step">
|
|
|
+ <!-- <div class="d_b_step">
|
|
|
<h2>第一步:下载模板文档</h2>
|
|
|
<p>点击下载模板文档来下载指定文档</p>
|
|
|
<el-button
|
|
@@ -24,41 +36,55 @@
|
|
|
@click="downloadTemplateDocx()"
|
|
|
>下载模板文档</el-button
|
|
|
>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
|
|
|
<div class="d_b_step">
|
|
|
- <h2>第二步:填入模板变量</h2>
|
|
|
+ <h2>第一步:填入模板变量</h2>
|
|
|
<p>按需制作排版Word模板文档,目前支持docx格式</p>
|
|
|
<p>
|
|
|
在文件中指定位置输入下方的"字段变量",用于显示真实数据的准确位置
|
|
|
</p>
|
|
|
-
|
|
|
- <h3>文本:</h3>
|
|
|
+
|
|
|
+ <h3>文本:</h3>
|
|
|
<img
|
|
|
src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/default%2F%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202410090922471728436994846.png"
|
|
|
/>
|
|
|
|
|
|
- <h3>选择题:</h3>
|
|
|
- <div class="d_b_s_imgList">
|
|
|
- <img src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/41728546186962.png">
|
|
|
- <img src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/51728546189479.png">
|
|
|
- </div>
|
|
|
- <div class="foldMenu">
|
|
|
- <span v-if="foldField" @click="foldField = false">折叠字段变量</span>
|
|
|
- <span v-if="!foldField" @click="foldField = true">显示字段变量</span>
|
|
|
- </div>
|
|
|
+ <h3>选择题:</h3>
|
|
|
+ <div class="d_b_s_imgList">
|
|
|
+ <img
|
|
|
+ src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/41728546186962.png"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/51728546189479.png"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="foldMenu">
|
|
|
+ <span v-if="foldField" @click="foldField = false"
|
|
|
+ >折叠字段变量</span
|
|
|
+ >
|
|
|
+ <span v-if="!foldField" @click="foldField = true"
|
|
|
+ >显示字段变量</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
<div
|
|
|
v-for="(item, index) in fieldList"
|
|
|
:key="index"
|
|
|
class="d_b_s_fieldListItem"
|
|
|
- v-if="foldField"
|
|
|
+ v-if="foldField"
|
|
|
>
|
|
|
<span
|
|
|
>{{ item.name }}:{{
|
|
|
"{" + (item.type == "image" ? "%" : "") + item.field + "}"
|
|
|
}}</span
|
|
|
>
|
|
|
- <span @click="copyContent(`{${item.type == 'image' ? '%' : ''}${item.field}}`)">
|
|
|
+ <span
|
|
|
+ @click="
|
|
|
+ copyContent(
|
|
|
+ `{${item.type == 'image' ? '%' : ''}${item.field}}`
|
|
|
+ )
|
|
|
+ "
|
|
|
+ >
|
|
|
<svg
|
|
|
width="14"
|
|
|
height="14"
|
|
@@ -80,7 +106,7 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="d_b_step">
|
|
|
+ <!-- <div class="d_b_step">
|
|
|
<h2>第三步:上传填入后的模板文档</h2>
|
|
|
<div v-if="uploadTemplateDocxData" class="d_b_s_fileCard">
|
|
|
<svg
|
|
@@ -115,16 +141,16 @@
|
|
|
@click="uploadTemplateDocx()"
|
|
|
>上传填入后的模板文档</el-button
|
|
|
>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
|
|
|
<div class="d_b_step">
|
|
|
- <h2>第四步:点击导出</h2>
|
|
|
+ <h2>第二步:点击导出</h2>
|
|
|
<p></p>
|
|
|
<el-button
|
|
|
class="d_b_s_button"
|
|
|
type="primary"
|
|
|
- :disabled="!uploadTemplateDocxData"
|
|
|
- @click="exportDocx()"
|
|
|
+ :disabled="!downFileData"
|
|
|
+ @click="exportDocx2()"
|
|
|
>导出Word文档</el-button
|
|
|
>
|
|
|
</div>
|
|
@@ -138,8 +164,15 @@
|
|
|
import PizZip from "pizzip";
|
|
|
import Docxtemplater from "docxtemplater";
|
|
|
import ImageModule from "docxtemplater-image-module-free";
|
|
|
-import { saveAs } from 'file-saver';
|
|
|
+import { saveAs } from "file-saver";
|
|
|
import topicVue from "../../testStudent/view/component/topic.vue";
|
|
|
+// import { renderAsync } from 'docx-preview/dist/docx-preview.js'
|
|
|
+import VueOfficeDocx from "@vue-office/docx";
|
|
|
+import "@vue-office/docx/lib/index.css";
|
|
|
+// import { renderAsync } from 'docx-preview/dist/docx-preview.js'
|
|
|
+import htmlDocx from "html-docx-js/dist/html-docx";
|
|
|
+import txtHtmlView from "./txtHtmlView.vue"
|
|
|
+// import a from './docx-preview.js'
|
|
|
const getFile = url => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
var credentials = {
|
|
@@ -181,9 +214,11 @@ const getFile = url => {
|
|
|
|
|
|
export default {
|
|
|
props: {},
|
|
|
- components:{
|
|
|
- topicVue
|
|
|
- },
|
|
|
+ components: {
|
|
|
+ topicVue,
|
|
|
+ VueOfficeDocx,
|
|
|
+ txtHtmlView
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
show: false,
|
|
@@ -200,8 +235,11 @@ export default {
|
|
|
],
|
|
|
uploadTemplateDocxData: null, //上传的模板文档
|
|
|
downFileData: null, // 下载模板文档的url
|
|
|
- checkJson:[],
|
|
|
- foldField:false,
|
|
|
+ checkJson: [],
|
|
|
+ foldField: false,
|
|
|
+ wordContent: "",
|
|
|
+ wordContentLoading: true,
|
|
|
+ courseId:"",
|
|
|
};
|
|
|
},
|
|
|
methods: {
|
|
@@ -210,46 +248,88 @@ export default {
|
|
|
done();
|
|
|
},
|
|
|
open(data) {
|
|
|
- this.init();
|
|
|
- let _fileData = data.fileData;
|
|
|
- this.downFileData = _fileData;
|
|
|
- this.checkJson = data.formData.array
|
|
|
- this.fieldList = this.getFieldData(data.formData.array)
|
|
|
+ this.init();
|
|
|
+ let _fileData = data.fileData;
|
|
|
+ this.downFileData = _fileData;
|
|
|
+ this.courseId = data.courseId
|
|
|
+ this.checkJson = data.formData.array;
|
|
|
+ this.fieldList = this.getFieldData(data.formData.array);
|
|
|
+ this.getWordContent(this.downFileData);
|
|
|
this.show = true;
|
|
|
},
|
|
|
close() {
|
|
|
this.show = false;
|
|
|
- this.init();
|
|
|
+ this.init();
|
|
|
},
|
|
|
- init() { // 初始化
|
|
|
- this.downFileData = null;
|
|
|
- this.fieldList = [];
|
|
|
- this.uploadTemplateDocxData = null;
|
|
|
- this.foldField = false;
|
|
|
+ init() {
|
|
|
+ // 初始化
|
|
|
+ this.downFileData = null;
|
|
|
+ this.fieldList = [];
|
|
|
+ this.uploadTemplateDocxData = null;
|
|
|
+ this.foldField = false;
|
|
|
},
|
|
|
|
|
|
- getFieldData(array){
|
|
|
- let _list = [];
|
|
|
- let _index = 0;
|
|
|
- for(let i=0;i<array.length;i++){
|
|
|
- let _item = array[i];
|
|
|
- if(_item.type == 3){
|
|
|
- let _item2 = _item.json;
|
|
|
- _list.push({name: _item2.title, field: `ti_${_index}`, type: "text", value: _item2.answer2})
|
|
|
- _index++;
|
|
|
- }else if(_item.type==1){
|
|
|
- let _item2 = _item.json;
|
|
|
- let choseTxt = ``
|
|
|
- _item2.array.forEach((i,index2)=>{
|
|
|
- choseTxt += `${(_item2.answer2===index2 || _item2.answer2.includes(index2)?'☑':'□')}${i.option} `
|
|
|
- })
|
|
|
- _list.push({name:_item2.title,field: `ti_${_index}`, type: "text", value: choseTxt})
|
|
|
- _index++;
|
|
|
- }
|
|
|
- }
|
|
|
- return _list;
|
|
|
- },
|
|
|
+ getFieldData(array) {
|
|
|
+ let _list = [];
|
|
|
+ let _index = 0;
|
|
|
+ for (let i = 0; i < array.length; i++) {
|
|
|
+ let _item = array[i];
|
|
|
+ if (_item.type == 3) {
|
|
|
+ let _item2 = _item.json;
|
|
|
+ _list.push({
|
|
|
+ name: _item2.title,
|
|
|
+ field: `ti_${_index}`,
|
|
|
+ type: "text",
|
|
|
+ value: _item2.answer2
|
|
|
+ });
|
|
|
+ _index++;
|
|
|
+ } else if (_item.type == 1) {
|
|
|
+ let _item2 = _item.json;
|
|
|
+ let choseTxt = ``;
|
|
|
+ _item2.array.forEach((i, index2) => {
|
|
|
+ choseTxt += `${
|
|
|
+ _item2.answer2 === index2 || _item2.answer2.includes(index2)
|
|
|
+ ? "☑"
|
|
|
+ : "□"
|
|
|
+ }${i.option} `;
|
|
|
+ });
|
|
|
+ _list.push({
|
|
|
+ name: _item2.title,
|
|
|
+ field: `ti_${_index}`,
|
|
|
+ type: "text",
|
|
|
+ value: choseTxt
|
|
|
+ });
|
|
|
+ _index++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return _list;
|
|
|
+ },
|
|
|
downloadTemplateDocx() {
|
|
|
+ const officeViewer = this.$refs.vueOfficeDocxRef;
|
|
|
+ // console.log(this.$refs.docxTemplateDialogRef)
|
|
|
+ // console.log(officeViewer)
|
|
|
+ const blob = new Blob([officeViewer.$el.innerHTML], {
|
|
|
+ type:
|
|
|
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
|
+ });
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
+ const a = document.createElement("a");
|
|
|
+ a.href = url;
|
|
|
+ a.download = this.downFileData.fileName;
|
|
|
+ a.click();
|
|
|
+ this.$message.success("下载成功");
|
|
|
+
|
|
|
+ // console.log(officeViewer.$data)
|
|
|
+ // officeViewer.exportDocx()
|
|
|
+ // officeViewer.getContent().then(content => {
|
|
|
+ // console.log(content)
|
|
|
+ // })
|
|
|
+ // console.log(this.$refs.vueOfficeDocxRef.$el);
|
|
|
+ // const el = this.$refs.vueOfficeDocxRef.$el;
|
|
|
+ // const body = el.querySelector(".docx");
|
|
|
+ // console.log("👉",body);
|
|
|
+ // this.generateDocx(this.downFileData.fileName,officeViewer.$el.innerHTML)
|
|
|
+ return;
|
|
|
getFile(this.downFileData.url).then(data => {
|
|
|
if (data.data != 1) {
|
|
|
// 下载文件, 并存成ArrayBuffer对象
|
|
@@ -288,6 +368,170 @@ export default {
|
|
|
// this.uploadWavFileAndGetText(file);
|
|
|
};
|
|
|
},
|
|
|
+ async exportDocx2() {
|
|
|
+ const el = this.$refs.vueOfficeDocxRef?this.$refs.vueOfficeDocxRef.$el:this.$refs.txtHtmlViewRef.$el;
|
|
|
+ console.log(el)
|
|
|
+ const body = el.querySelector(".docx-wrapper");
|
|
|
+
|
|
|
+ let _html = body.innerHTML;
|
|
|
+
|
|
|
+ for(let i = 0;i<this.fieldList.length;i++){
|
|
|
+ if(this.fieldList[i].type == 'image'){
|
|
|
+ const img = await this.convertImageUrlToBase64(this.fieldList[i].value)
|
|
|
+ _html = _html.replaceAll(`{%${this.fieldList[i].field}}`,`<img src="${img.url}" width="${img.width}" height="${img.height}" />`)
|
|
|
+ }else if(this.fieldList[i].type == 'text'){
|
|
|
+ _html = _html.replaceAll(`{${this.fieldList[i].field}}`,this.fieldList[i].value)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // this.fieldList.forEach(i => {
|
|
|
+ // _html = _html.replace(`{${i.field}}`,i.value)
|
|
|
+ // })
|
|
|
+ // 下载word文档
|
|
|
+ await this.generateDocx(this.downFileData.fileName,_html)
|
|
|
+
|
|
|
+ if(!this.downFileData.txtUrl || this.downFileData.txt !== el.innerHTML){
|
|
|
+ let txt = el.innerHTML;
|
|
|
+ // 创建Blob对象
|
|
|
+ const blob = new Blob([txt], { type: "text/plain;charset=utf-8" });
|
|
|
+ blob.lastModifiedDate = new Date();
|
|
|
+ blob.name = `${this.downFileData.fileName}_wordHtml.txt`;
|
|
|
+ let url = await this.uploadFile(blob)
|
|
|
+
|
|
|
+ if(url && this.courseId){
|
|
|
+ console.log("修改文件")
|
|
|
+ console.log(url)
|
|
|
+ console.log(this.courseId)
|
|
|
+ this.downFileData.txt = txt
|
|
|
+ this.downFileData.txtUrl = url
|
|
|
+ this.changeDownFileData(this.downFileData)
|
|
|
+ this.$forceUpdate();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // const uploadBlob = await this.getGenerateDocxHtml(body.out)
|
|
|
+
|
|
|
+ // let reader = new FileReader();
|
|
|
+ // reader.readAsArrayBuffer(uploadBlob);
|
|
|
+ // reader.onload = async e => {
|
|
|
+ // try {
|
|
|
+ // const binary = new Uint8Array(reader.result);
|
|
|
+ // //创建一个PizZip实例
|
|
|
+ // const zip = new PizZip(binary);
|
|
|
+ // // 将模板内容加载到 Docxtemplater 中
|
|
|
+ // const doc = new Docxtemplater().loadZip(zip);
|
|
|
+ // const output = doc.getZip().generate({
|
|
|
+ // type: "blob",
|
|
|
+ // mimeType:
|
|
|
+ // "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
|
+ // compression: "DEFLATE"
|
|
|
+ // });
|
|
|
+
|
|
|
+ // const file = new File([output],this.downFileData.fileName,{type:".docx",lastModified:new Date().getTime()})
|
|
|
+
|
|
|
+ // const url = await this.uploadFile(file)
|
|
|
+ // console.log(url)
|
|
|
+
|
|
|
+ // }catch(e){
|
|
|
+ // console.log(e)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // const file = new File([uploadBlob],this.downFileData.fileName,{type:".docx",lastModified:new Date().getTime()})
|
|
|
+
|
|
|
+ // const url = await this.uploadFile(file)
|
|
|
+ // console.log(url)
|
|
|
+ // if(url){
|
|
|
+
|
|
|
+ // }else{
|
|
|
+
|
|
|
+ // }
|
|
|
+ return
|
|
|
+ // const blob = await this.getGenerateDocxHtml(body.innerHTML);
|
|
|
+ // if (!blob) return this.$message.error("导出失败");
|
|
|
+
|
|
|
+ // let reader = new FileReader();
|
|
|
+ // reader.readAsArrayBuffer(blob);
|
|
|
+ // reader.onload = async e => {
|
|
|
+ // try {
|
|
|
+ // this.loading = true;
|
|
|
+ // const binary = new Uint8Array(reader.result);
|
|
|
+ // //创建一个PizZip实例
|
|
|
+ // const zip = new PizZip(binary);
|
|
|
+ // // 将模板内容加载到 Docxtemplater 中
|
|
|
+ // const doc = new Docxtemplater().loadZip(zip);
|
|
|
+
|
|
|
+ // let _data = {};
|
|
|
+ // let _image = {};
|
|
|
+ // // 设置模板值
|
|
|
+ // // this.fieldList.forEach(i => {
|
|
|
+ // // _data[i.field] = i.value;
|
|
|
+ // // });
|
|
|
+ // for (let i = 0; i < this.fieldList.length; i++) {
|
|
|
+ // // console.log(this.fieldList[i])
|
|
|
+ // if (this.fieldList[i].type == "text") {
|
|
|
+ // //文本处理
|
|
|
+ // _data[this.fieldList[i].field] = this.fieldList[i].value;
|
|
|
+ // } else if (this.fieldList[i].type == "image") {
|
|
|
+ // //图片处理
|
|
|
+ // let _imageObj = await this.convertImageUrlToBase64(
|
|
|
+ // this.fieldList[i].value
|
|
|
+ // );
|
|
|
+ // _data[this.fieldList[i].field] = _imageObj.url;
|
|
|
+ // _image[this.fieldList[i].field] = {
|
|
|
+ // width: _imageObj.width,
|
|
|
+ // height: _imageObj.height
|
|
|
+ // };
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // // return this.loading = false;
|
|
|
+
|
|
|
+ // // 图片处理
|
|
|
+ // const opts = {
|
|
|
+ // centered: false,
|
|
|
+ // fileType: "docx",
|
|
|
+ // getImage: (value, value2, value3) => {
|
|
|
+ // return this.base64DataURLToArrayBuffer(value);
|
|
|
+ // },
|
|
|
+ // getSize: (arrayValue, value, tagName) => {
|
|
|
+ // // console.log(_image)
|
|
|
+ // // console.log(tagName)
|
|
|
+ // let newWidth = _image[tagName].width;
|
|
|
+ // let newHeight = _image[tagName].height;
|
|
|
+
|
|
|
+ // // let newWidth = 550;
|
|
|
+ // // let newHeight = 100;
|
|
|
+ // return [newWidth, newHeight];
|
|
|
+ // }
|
|
|
+ // };
|
|
|
+ // console.log()
|
|
|
+ // doc.attachModule(new ImageModule(opts));
|
|
|
+ // //渲染模板
|
|
|
+ // doc.setData(_data);
|
|
|
+ // doc.render();
|
|
|
+ // //获取渲染后的文本
|
|
|
+ // const output = doc.getZip().generate({
|
|
|
+ // type: "blob",
|
|
|
+ // mimeType:
|
|
|
+ // "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
|
+ // compression: "DEFLATE"
|
|
|
+ // });
|
|
|
+
|
|
|
+ // saveAs(output, `${this.downFileData.fileName}`);
|
|
|
+ // // let link = document.createElement("a");
|
|
|
+ // // link.download = this.uploadTemplateDocxData.name;
|
|
|
+ // // link.style.display = "none";
|
|
|
+ // // let blob = new Blob([output]);
|
|
|
+ // // link.href = URL.createObjectURL(blob);
|
|
|
+ // // document.body.appendChild(link);
|
|
|
+ // // link.click();
|
|
|
+ // // document.body.removeChild(link);
|
|
|
+ // this.loading = false;
|
|
|
+ // this.$message.success("导出成功");
|
|
|
+ // } catch (error) {
|
|
|
+ // console.log(error);
|
|
|
+ // this.loading = false;
|
|
|
+ // return this.$message.error("导出失败");
|
|
|
+ // }
|
|
|
+ // };
|
|
|
+ },
|
|
|
async exportDocx() {
|
|
|
if (!this.uploadTemplateDocxData)
|
|
|
return this.$message.error("请先上传模板文档");
|
|
@@ -309,7 +553,7 @@ export default {
|
|
|
// _data[i.field] = i.value;
|
|
|
// });
|
|
|
for (let i = 0; i < this.fieldList.length; i++) {
|
|
|
- // console.log(this.fieldList[i])
|
|
|
+ // console.log(this.fieldList[i])
|
|
|
if (this.fieldList[i].type == "text") {
|
|
|
//文本处理
|
|
|
_data[this.fieldList[i].field] = this.fieldList[i].value;
|
|
@@ -325,7 +569,7 @@ export default {
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
- // return this.loading = false;
|
|
|
+ // return this.loading = false;
|
|
|
|
|
|
// 图片处理
|
|
|
const opts = {
|
|
@@ -335,17 +579,17 @@ export default {
|
|
|
return this.base64DataURLToArrayBuffer(value);
|
|
|
},
|
|
|
getSize: (arrayValue, value, tagName) => {
|
|
|
- // console.log(_image)
|
|
|
- // console.log(tagName)
|
|
|
+ // console.log(_image)
|
|
|
+ // console.log(tagName)
|
|
|
let newWidth = _image[tagName].width;
|
|
|
let newHeight = _image[tagName].height;
|
|
|
|
|
|
- // let newWidth = 550;
|
|
|
+ // let newWidth = 550;
|
|
|
// let newHeight = 100;
|
|
|
return [newWidth, newHeight];
|
|
|
}
|
|
|
};
|
|
|
- doc.attachModule(new ImageModule(opts));
|
|
|
+ doc.attachModule(new ImageModule(opts));
|
|
|
//渲染模板
|
|
|
doc.setData(_data);
|
|
|
doc.render();
|
|
@@ -357,7 +601,7 @@ export default {
|
|
|
compression: "DEFLATE"
|
|
|
});
|
|
|
|
|
|
- saveAs(output,`${this.uploadTemplateDocxData.name}`)
|
|
|
+ saveAs(output, `${this.uploadTemplateDocxData.name}`);
|
|
|
// let link = document.createElement("a");
|
|
|
// link.download = this.uploadTemplateDocxData.name;
|
|
|
// link.style.display = "none";
|
|
@@ -416,9 +660,9 @@ export default {
|
|
|
};
|
|
|
|
|
|
img.onerror = error => {
|
|
|
- console.log("图片转base64失败")
|
|
|
- console.log(error)
|
|
|
- resolve({url:"",width:0,height:0});
|
|
|
+ console.log("图片转base64失败");
|
|
|
+ console.log(error);
|
|
|
+ resolve({ url: "", width: 0, height: 0 });
|
|
|
};
|
|
|
});
|
|
|
},
|
|
@@ -441,7 +685,388 @@ export default {
|
|
|
bytes[i] = ascii;
|
|
|
}
|
|
|
return bytes.buffer;
|
|
|
- }
|
|
|
+ },
|
|
|
+ async getWordContent(fileData) {
|
|
|
+ console.log(fileData);
|
|
|
+ this.wordContentLoading = true;
|
|
|
+ return (this.wordContentLoading = false);
|
|
|
+ try {
|
|
|
+ // console.log(a)
|
|
|
+ // let response = await getFile(fileData.url);
|
|
|
+ // if (response.data == 1) {
|
|
|
+ // this.wordContentLoading = false;
|
|
|
+ // return this.$message.error("文件不存在");
|
|
|
+ // }
|
|
|
+
|
|
|
+ // await renderAsync(response.data,this.$refs.wordAreaRef);
|
|
|
+ this.wordContentLoading = false;
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ this.wordContentLoading = false;
|
|
|
+ this.$message.error("加载文件失败");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 导出docx
|
|
|
+ async generateDocx(name, html) {
|
|
|
+ // 将html文件中需要用到的数据挂载到store上
|
|
|
+ const content = `<!DOCTYPE html>
|
|
|
+ <html xmlns:v='urn:schemas-microsoft-com
|
|
|
+ :vml'xmlns:o='urn:schemas-microsoft-com:office
|
|
|
+ :office'xmlns:w='urn:schemas-microsoft-com:office
|
|
|
+ :word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
|
|
|
+ xmlns='http://www.w3.org/TR/REC-html40'
|
|
|
+ xmlns='http://www.w3.org/1999/xhtml'>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>${name}</title>
|
|
|
+ <style>
|
|
|
+ *{
|
|
|
+ font-family: '宋体';
|
|
|
+ margin:0;
|
|
|
+ padding:0;
|
|
|
+ line-height:1;
|
|
|
+ }
|
|
|
+ table {
|
|
|
+ border-collapse: collapse; /* 折叠边框 */
|
|
|
+ width: 100%;
|
|
|
+ font-size:10.5pt;
|
|
|
+ }
|
|
|
+ th, td {
|
|
|
+ border: 1px solid black; /* 线条样式 */
|
|
|
+ padding: 8px;
|
|
|
+ text-align: left;
|
|
|
+ font-size:10.5pt;
|
|
|
+ }
|
|
|
+ ol,ul{
|
|
|
+ margin:0;
|
|
|
+ padding:0;
|
|
|
+ margin-right:-1in;
|
|
|
+ }
|
|
|
+ li{
|
|
|
+ margin-bottom:0.1in
|
|
|
+ margin-right:-1in;
|
|
|
+ }
|
|
|
+ p{
|
|
|
+ line-height:1;
|
|
|
+ margin:0;
|
|
|
+ padding:0
|
|
|
+ }
|
|
|
+ .vue-office-docx{height:100%;overflow-y:auto}
|
|
|
+ .vue-office-docx .docx-wrapper>section.docx{margin-bottom:5px}
|
|
|
+ @media screen and (max-width: 800px){
|
|
|
+ .vue-office-docx .docx-wrapper{padding:10px}
|
|
|
+ .vue-office-docx .docx-wrapper>section.docx{padding:10px!important;width:100%!important}
|
|
|
+ }
|
|
|
+
|
|
|
+.docx-wrapper { background: gray; padding: 30px; padding-bottom: 0px; display: flex; flex-flow: column; align-items: center; }
|
|
|
+.docx-wrapper>section.docx { background: white; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); margin-bottom: 30px; }
|
|
|
+.docx { color: black; hyphens: auto; text-underline-position: from-font; }
|
|
|
+section.docx { box-sizing: border-box; display: flex; flex-flow: column nowrap; position: relative; overflow: hidden; }
|
|
|
+section.docx>article { margin-bottom: auto; z-index: 1; }
|
|
|
+section.docx>footer { z-index: 1; }
|
|
|
+.docx table { border-collapse: collapse; }
|
|
|
+.docx table td, .docx table th { vertical-align: top; }
|
|
|
+.docx p { margin: 0pt; min-height: 1em; }
|
|
|
+.docx span { white-space: pre-wrap; overflow-wrap: break-word; }
|
|
|
+.docx a { color: inherit; text-decoration: inherit; }
|
|
|
+.docx svg { fill: transparent; }
|
|
|
+.docx {
|
|
|
+ --docx-majorHAnsi-font: Calibri Light;
|
|
|
+ --docx-minorHAnsi-font: Calibri;
|
|
|
+ --docx-dk1-color: #000000;
|
|
|
+ --docx-lt1-color: #FFFFFF;
|
|
|
+ --docx-dk2-color: #44546A;
|
|
|
+ --docx-lt2-color: #E7E6E6;
|
|
|
+ --docx-accent1-color: #5B9BD5;
|
|
|
+ --docx-accent2-color: #ED7D31;
|
|
|
+ --docx-accent3-color: #A5A5A5;
|
|
|
+ --docx-accent4-color: #FFC000;
|
|
|
+ --docx-accent5-color: #4472C4;
|
|
|
+ --docx-accent6-color: #70AD47;
|
|
|
+ --docx-hlink-color: #0563C1;
|
|
|
+ --docx-folHlink-color: #954F72;
|
|
|
+}
|
|
|
+.docx span {
|
|
|
+ font-family: Times New Roman;
|
|
|
+}
|
|
|
+.docx p, p.docx_1 {
|
|
|
+ text-align: justify;
|
|
|
+}
|
|
|
+.docx p, p.docx_1 span {
|
|
|
+ font-family: var(--docx-minorHAnsi-font);
|
|
|
+ min-height: 10.50pt;
|
|
|
+ font-size: 10.50pt;
|
|
|
+}
|
|
|
+.docx table, table.docx_2 td {
|
|
|
+ padding-top: 0.00pt;
|
|
|
+ padding-left: 5.40pt;
|
|
|
+ padding-bottom: 0.00pt;
|
|
|
+ padding-right: 5.40pt;
|
|
|
+}
|
|
|
+table.docx_3 p {
|
|
|
+ text-align: justify;
|
|
|
+}
|
|
|
+table.docx_3 td {
|
|
|
+ border-top: 0.50pt solid black;
|
|
|
+ border-left: 0.50pt solid black;
|
|
|
+ border-bottom: 0.50pt solid black;
|
|
|
+ border-right: 0.50pt solid black;
|
|
|
+ padding-top: 0.00pt;
|
|
|
+ padding-left: 5.40pt;
|
|
|
+ padding-bottom: 0.00pt;
|
|
|
+ padding-right: 5.40pt;
|
|
|
+}
|
|
|
+ p.docx-num-2-0:before {
|
|
|
+ content: ""counter(docx-num-2-0, decimal)"、";
|
|
|
+ counter-increment: docx-num-2-0;
|
|
|
+}
|
|
|
+p.docx-num-2-0 {
|
|
|
+ display: list-item;
|
|
|
+ list-style-position: inside;
|
|
|
+ list-style-type: none;
|
|
|
+}
|
|
|
+p.docx-num-1-0:before {
|
|
|
+ content: ""counter(docx-num-1-0, decimal)"、";
|
|
|
+ counter-increment: docx-num-1-0;
|
|
|
+}
|
|
|
+p.docx-num-1-0 {
|
|
|
+ display: list-item;
|
|
|
+ list-style-position: inside;
|
|
|
+ list-style-type: none;
|
|
|
+}
|
|
|
+.docx-wrapper {
|
|
|
+ counter-reset: docx-num-2-0 4 docx-num-1-0 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </style>
|
|
|
+ </head>
|
|
|
+ <body>
|
|
|
+ ${html}
|
|
|
+ </body>
|
|
|
+ </html>`;
|
|
|
+ // console.log(content)
|
|
|
+ // return console.log(content)
|
|
|
+ // debugger
|
|
|
+ let blob = htmlDocx.asBlob(content);
|
|
|
+
|
|
|
+ // const uploadFile = new File([blob], `${name}.docx`, {
|
|
|
+ // type:
|
|
|
+ // "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
|
+ // });
|
|
|
+ saveAs(blob, `${name}.docx`);
|
|
|
+ return true;
|
|
|
+ // this.beforeUploadHtml(uploadFile);
|
|
|
+ },
|
|
|
+ async getGenerateDocxHtml(html) {
|
|
|
+ const content = `<!DOCTYPE html>
|
|
|
+ <html xmlns:v='urn:schemas-microsoft-com
|
|
|
+ :vml'xmlns:o='urn:schemas-microsoft-com:office
|
|
|
+ :office'xmlns:w='urn:schemas-microsoft-com:office
|
|
|
+ :word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
|
|
|
+ xmlns='http://www.w3.org/TR/REC-html40'
|
|
|
+ xmlns='http://www.w3.org/1999/xhtml'>
|
|
|
+ <head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>DOCX</title>
|
|
|
+ <style>
|
|
|
+ *{
|
|
|
+ font-family: '宋体';
|
|
|
+ margin:0;
|
|
|
+ padding:0;
|
|
|
+ line-height:1;
|
|
|
+ }
|
|
|
+ table {
|
|
|
+ border-collapse: collapse; /* 折叠边框 */
|
|
|
+ width: 100%;
|
|
|
+ font-size:10.5pt;
|
|
|
+ }
|
|
|
+ th, td {
|
|
|
+ border: 1px solid black; /* 线条样式 */
|
|
|
+ padding: 8px;
|
|
|
+ text-align: left;
|
|
|
+ font-size:10.5pt;
|
|
|
+ }
|
|
|
+ ol,ul{
|
|
|
+ margin:0;
|
|
|
+ padding:0;
|
|
|
+ margin-right:-1in;
|
|
|
+ }
|
|
|
+ li{
|
|
|
+ margin-bottom:0.1in
|
|
|
+ margin-right:-1in;
|
|
|
+ }
|
|
|
+ p{
|
|
|
+ line-height:1;
|
|
|
+ margin:0;
|
|
|
+ padding:0
|
|
|
+ }
|
|
|
+ .vue-office-docx{height:100%;overflow-y:auto}
|
|
|
+ .vue-office-docx .docx-wrapper>section.docx{margin-bottom:5px}
|
|
|
+ @media screen and (max-width: 800px){
|
|
|
+ .vue-office-docx .docx-wrapper{padding:10px}
|
|
|
+ .vue-office-docx .docx-wrapper>section.docx{padding:10px!important;width:100%!important}
|
|
|
+ }
|
|
|
+
|
|
|
+.docx-wrapper { background: gray; padding: 30px; padding-bottom: 0px; display: flex; flex-flow: column; align-items: center; }
|
|
|
+.docx-wrapper>section.docx { background: white; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); margin-bottom: 30px; }
|
|
|
+.docx { color: black; hyphens: auto; text-underline-position: from-font; }
|
|
|
+section.docx { box-sizing: border-box; display: flex; flex-flow: column nowrap; position: relative; overflow: hidden; }
|
|
|
+section.docx>article { margin-bottom: auto; z-index: 1; }
|
|
|
+section.docx>footer { z-index: 1; }
|
|
|
+.docx table { border-collapse: collapse; }
|
|
|
+.docx table td, .docx table th { vertical-align: top; }
|
|
|
+.docx p { margin: 0pt; min-height: 1em; }
|
|
|
+.docx span { white-space: pre-wrap; overflow-wrap: break-word; }
|
|
|
+.docx a { color: inherit; text-decoration: inherit; }
|
|
|
+.docx svg { fill: transparent; }
|
|
|
+.docx {
|
|
|
+ --docx-majorHAnsi-font: Calibri Light;
|
|
|
+ --docx-minorHAnsi-font: Calibri;
|
|
|
+ --docx-dk1-color: #000000;
|
|
|
+ --docx-lt1-color: #FFFFFF;
|
|
|
+ --docx-dk2-color: #44546A;
|
|
|
+ --docx-lt2-color: #E7E6E6;
|
|
|
+ --docx-accent1-color: #5B9BD5;
|
|
|
+ --docx-accent2-color: #ED7D31;
|
|
|
+ --docx-accent3-color: #A5A5A5;
|
|
|
+ --docx-accent4-color: #FFC000;
|
|
|
+ --docx-accent5-color: #4472C4;
|
|
|
+ --docx-accent6-color: #70AD47;
|
|
|
+ --docx-hlink-color: #0563C1;
|
|
|
+ --docx-folHlink-color: #954F72;
|
|
|
+}
|
|
|
+.docx span {
|
|
|
+ font-family: Times New Roman;
|
|
|
+}
|
|
|
+.docx p, p.docx_1 {
|
|
|
+ text-align: justify;
|
|
|
+}
|
|
|
+.docx p, p.docx_1 span {
|
|
|
+ font-family: var(--docx-minorHAnsi-font);
|
|
|
+ min-height: 10.50pt;
|
|
|
+ font-size: 10.50pt;
|
|
|
+}
|
|
|
+.docx table, table.docx_2 td {
|
|
|
+ padding-top: 0.00pt;
|
|
|
+ padding-left: 5.40pt;
|
|
|
+ padding-bottom: 0.00pt;
|
|
|
+ padding-right: 5.40pt;
|
|
|
+}
|
|
|
+table.docx_3 p {
|
|
|
+ text-align: justify;
|
|
|
+}
|
|
|
+table.docx_3 td {
|
|
|
+ border-top: 0.50pt solid black;
|
|
|
+ border-left: 0.50pt solid black;
|
|
|
+ border-bottom: 0.50pt solid black;
|
|
|
+ border-right: 0.50pt solid black;
|
|
|
+ padding-top: 0.00pt;
|
|
|
+ padding-left: 5.40pt;
|
|
|
+ padding-bottom: 0.00pt;
|
|
|
+ padding-right: 5.40pt;
|
|
|
+}
|
|
|
+ p.docx-num-2-0:before {
|
|
|
+ content: ""counter(docx-num-2-0, decimal)"、";
|
|
|
+ counter-increment: docx-num-2-0;
|
|
|
+}
|
|
|
+p.docx-num-2-0 {
|
|
|
+ display: list-item;
|
|
|
+ list-style-position: inside;
|
|
|
+ list-style-type: none;
|
|
|
+}
|
|
|
+p.docx-num-1-0:before {
|
|
|
+ content: ""counter(docx-num-1-0, decimal)"、";
|
|
|
+ counter-increment: docx-num-1-0;
|
|
|
+}
|
|
|
+p.docx-num-1-0 {
|
|
|
+ display: list-item;
|
|
|
+ list-style-position: inside;
|
|
|
+ list-style-type: none;
|
|
|
+}
|
|
|
+.docx-wrapper {
|
|
|
+ counter-reset: docx-num-2-0 4 docx-num-1-0 0;
|
|
|
+}
|
|
|
+</style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+${html}
|
|
|
+</body>
|
|
|
+</html>`;
|
|
|
+// console.log(content)
|
|
|
+// return console.log(content)
|
|
|
+// debugger
|
|
|
+let blob = htmlDocx.asBlob(content);
|
|
|
+return blob;
|
|
|
+ },
|
|
|
+ uploadFile(file) {
|
|
|
+ return new Promise((resolve,reject) => {
|
|
|
+ var credentials = {
|
|
|
+ accessKeyId: "AKIATLPEDU37QV5CHLMH",
|
|
|
+ secretAccessKey: "Q2SQw37HfolS7yeaR1Ndpy9Jl4E2YZKUuuy2muZR"
|
|
|
+ }; //秘钥形式的登录上传
|
|
|
+ window.AWS.config.update(credentials);
|
|
|
+ window.AWS.config.region = "cn-northwest-1"; //设置区域
|
|
|
+
|
|
|
+ var bucket = new window.AWS.S3({ params: { Bucket: "ccrb" } }); //选择桶
|
|
|
+ var _this = this;
|
|
|
+
|
|
|
+ if (file) {
|
|
|
+ // this.loading = true;
|
|
|
+ var params = {
|
|
|
+ Key:
|
|
|
+ file.name.split(".")[0] +
|
|
|
+ new Date().getTime() +
|
|
|
+ "." +
|
|
|
+ file.name.split(".")[file.name.split(".").length - 1],
|
|
|
+ ContentType: file.type,
|
|
|
+ Body: file,
|
|
|
+ "Access-Control-Allow-Credentials": "*",
|
|
|
+ ACL: "public-read"
|
|
|
+ }; //key可以设置为桶的相抵路径,Body为文件, ACL最好要设置
|
|
|
+ var options = {
|
|
|
+ partSize: 2048 * 1024 * 1024,
|
|
|
+ queueSize: 2,
|
|
|
+ leavePartsOnError: true
|
|
|
+ };
|
|
|
+ bucket
|
|
|
+ .upload(params, options)
|
|
|
+ .on("httpUploadProgress", function(evt) {
|
|
|
+ //这里可以写进度条
|
|
|
+ _this.progressData.value = parseInt((evt.loaded * 100) / evt.total);
|
|
|
+ // console.log("Uploaded : " + parseInt((evt.loaded * 80) / evt.total) + '%');
|
|
|
+ })
|
|
|
+ .send(function(err, data) {
|
|
|
+ if (err) {
|
|
|
+ _this.$message.error("上传失败");
|
|
|
+ } else {
|
|
|
+ resolve(data.Location)
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ changeDownFileData(data){
|
|
|
+ let _data = JSON.parse(JSON.stringify(data))
|
|
|
+ delete _data.txt;
|
|
|
+
|
|
|
+ let params = [{
|
|
|
+ cid:this.courseId,
|
|
|
+ ncover:JSON.stringify(_data),
|
|
|
+ }]
|
|
|
+ this.$emit("changeCover",JSON.stringify(_data))
|
|
|
+ this.ajax.post(this.$store.state.api+"update_testCourseCoverById",params).then(res=>{
|
|
|
+ console.log(res.data)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getTxtContent(txt){
|
|
|
+ this.downFileData.txt = txt
|
|
|
+ },
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
@@ -493,13 +1118,16 @@ export default {
|
|
|
}
|
|
|
|
|
|
.b_left {
|
|
|
- flex: 1;
|
|
|
- height: 100%;
|
|
|
+ width: 630pt;
|
|
|
+ height: 100%;
|
|
|
+ border: none;
|
|
|
+ outline: none;
|
|
|
}
|
|
|
|
|
|
.b_right {
|
|
|
- min-width: 700px;
|
|
|
- max-width: 700px;
|
|
|
+ flex: 1;
|
|
|
+ /* min-width: 700px;
|
|
|
+ max-width: 700px; */
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
@@ -522,8 +1150,8 @@ export default {
|
|
|
margin-bottom: 10px;
|
|
|
}
|
|
|
|
|
|
-.d_b_step>h3{
|
|
|
- margin-top: 20px;
|
|
|
+.d_b_step > h3 {
|
|
|
+ margin-top: 20px;
|
|
|
}
|
|
|
|
|
|
.d_b_step > p {
|
|
@@ -603,25 +1231,24 @@ export default {
|
|
|
color: #e60012;
|
|
|
}
|
|
|
|
|
|
-.d_b_s_imgList{
|
|
|
- margin-top: 10px;
|
|
|
+.d_b_s_imgList {
|
|
|
+ margin-top: 10px;
|
|
|
}
|
|
|
|
|
|
-.d_b_s_imgList>img{
|
|
|
- width: 100%;
|
|
|
+.d_b_s_imgList > img {
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
|
|
|
-.foldMenu{
|
|
|
- width: 100%;
|
|
|
- display: flex;
|
|
|
- justify-content: flex-end;
|
|
|
- margin: 10px 0;
|
|
|
-
|
|
|
+.foldMenu {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ margin: 10px 0;
|
|
|
}
|
|
|
|
|
|
-.foldMenu>span{
|
|
|
- cursor: pointer;
|
|
|
- color: #409EFF;
|
|
|
- font-size: 16px;
|
|
|
+.foldMenu > span {
|
|
|
+ cursor: pointer;
|
|
|
+ color: #409eff;
|
|
|
+ font-size: 16px;
|
|
|
}
|
|
|
</style>
|