Files
desktop-app/public/plugins/export_pdf/plugin.js
2020-06-28 11:00:33 +08:00

385 lines
9.3 KiB
JavaScript

/**
* 导出PDF插件
* @author life life@leanote.com
* 选择目录, 将图片保存到文件夹中, 有个html文件(以笔记名命名)
* 注意, fs.existsSync总返回false, readFileSync可用
*/
define(function () {
var async; // = require('async');
var exportPDF = {
langs: {
'en-us': {
'export': 'Export PDF',
'Exporting': 'Exporting',
'Exporting: ': 'Exporting: ',
'exportSuccess': 'PDF saved successful!',
'exportFailure': 'PDF saved failure!',
},
'de-de': {
'export': 'Als PDF exportieren',
'Exporting': 'Exportiere',
'Exporting: ': 'Exportiere: ',
'exportSuccess': 'PDF erfolgreich gespeichert!',
'exportFailure': 'PDF speichern fehlgeschlagen!',
},
'zh-cn': {
'export': '导出PDF',
'Exporting': '正在导出',
'Exporting: ': '正在导出: ',
'exportSuccess': 'PDF导出成功!',
'exportFailure': 'PDF导出失败!'
},
'zh-hk': {
'export': '導出PDF',
'Exporting': '正在導出',
'Exporting: ': '正在導出: ',
'exportSuccess': 'PDF導出成功!',
'exportFailure': 'PDF導出失敗!'
}
},
_inited: false,
init: function () {
var me = this;
if (me._inited) {
return;
}
async = require('async');
me._inited = true;
me._initExportPdf();
},
// 调用main导出pdf
_exportPdfSeq: 1,
_exportPdfCallback: {},
_initExportPdf: function () {
var me = this;
// console.log('_initExportPdf');
Api.ipc.on('export-pdf-ret', function (event, arg) {
var seq = arg.seq;
// console.log('export-pdf-ret');
// console.log(arg);
// console.log(me._exportPdfCallback[seq]);
if (me._exportPdfCallback[seq]) {
me._exportPdfCallback[seq](arg);
}
});
},
exportPdf: function (htmlPath, targetPdfPath, isMarkdown, callback) {
this._exportPdfSeq++;
this._exportPdfCallback[this._exportPdfSeq] = callback;
Api.ipc.send('export-pdf',
{ htmlPath: htmlPath, targetPdfPath: targetPdfPath, isMarkdown: isMarkdown, seq: this._exportPdfSeq });
},
getPluginPath: function () {
return Api.evtService.getProjectBasePath() + '/public/plugins/export_pdf';
},
htmlTpl: '',
markdownTpl: '',
getTpl: function (isMarkdown) {
var tpl = isMarkdown ? this.markdownTpl : this.htmlTpl;
if (tpl) {
return tpl;
}
var basePluginPath = this.getPluginPath();
var tplName = isMarkdown ? 'markdown' : 'html';
var tplPath = basePluginPath + '/tpl/' + tplName + '.tpl';
tpl = Api.nodeFs.readFileSync(tplPath, 'utf-8');
isMarkdown ? (this.markdownTpl = tpl) : (this.htmlTpl = tpl);
return tpl;
},
// 生成html或markdown
render: function (note) {
var tpl = this.getTpl(note.IsMarkdown);
var title = note.Title || getMsg('Untitled');
tpl = tpl.replace(/\{title\}/g, title);
tpl = tpl.replace("{content}", function () {
return note.Content; // 为什么要这样? 因为 $$ 替换后变成了一个!!
});
return tpl;
},
replaceAll: function (src, pattern, to) {
if (!src) {
return src;
}
while (true) {
var oldSrc = src;
src = src.replace(pattern, to);
if (oldSrc === src) {
return src;
}
}
},
fixFilename: function (filename) {
var reg = new RegExp("/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\", 'g');
filename = filename.replace(reg, "-");
// 防止出现两个连续的-
while (filename.indexOf('--') != -1) {
filename = this.replaceAll(filename, '--', '-');
}
if (filename.length > 1) {
// 最后一个-
filename = filename.replace(/\-$/, '');
}
return filename;
},
// 得到可用的文件名, 避免冲突
getPdfFilePath: function (pathInfo, n, cb) {
var me = this;
if (n > 1) {
pathInfo.nameNotExt = pathInfo.nameNotExtRaw + '-' + n;
}
var absPath = pathInfo.getFullPath();
// Api.nodeFs.existsSync(absPath) 总是返回false, 不知道什么原因
// 在控制台上是可以的
Api.nodeFs.exists(absPath, function (exists) {
if (!exists) {
cb(absPath);
}
else {
me.getPdfFilePath(pathInfo, n + 1, cb);
}
});
},
getTargetPath: function (callback) {
// showSaveDialog 不支持property选择文件夹
var po = Api.gui.dialog.showOpenDialog(Api.gui.getCurrentWindow(),
{
defaultPath: Api.gui.app.getPath('userDesktop') + '/',
properties: ['openDirectory']
},
function (targetPath) {
callback(targetPath);
}
);
if(typeof(po) != "object"){
return;
}
po.then(function(re){
if(re.canceled !== false || re.filePaths.length < 1){
return;
}
callback(re.filePaths[0]);
},
function(err){
alert(err);
}
);
},
loadingIsClosed: false,
exportPDFForNotebook: function (notebookId) {
var me = this;
if (!notebookId) {
return;
}
me.getTargetPath(function (targetPath) {
if (!targetPath) {
return;
}
me.loadingIsClosed = false;
Api.loading.show(Api.getMsg('plugin.export_pdf.Exporting'),
{
hasProgress: true,
isLarge: true,
onClose: function () {
me.loadingIsClosed = true;
setTimeout(function () {
me.hideLoading();
});
}
});
Api.loading.setProgress(1);
Api.noteService.getNotes(notebookId, function (notes) {
if (!notes) {
me.hideLoading();
return;
}
var total = notes.length;
var i = 0;
async.eachSeries(notes, function (note, cb) {
if (me.loadingIsClosed) {
cb();
me.hideLoading();
return;
}
i++;
Api.loading.setProgress(100 * i / total);
me._exportPDF(note, targetPath, function () {
cb();
}, i, total);
}, function () {
me.hideLoading();
Notify.show({ title: 'Info', body: getMsg('plugin.export_pdf.exportSuccess') });
});
});
});
},
hideLoading: function () {
setTimeout(function () {
Api.loading.hide();
}, 1000);
},
exportPDF: function (noteIds) {
var me = this;
if (!noteIds || noteIds.length == 0) {
return;
}
me.getTargetPath(function (targetPath) {
if (!targetPath) {
return;
}
me.loadingIsClosed = false;
Api.loading.show(Api.getMsg('plugin.export_pdf.Exporting'),
{
hasProgress: true,
isLarge: true,
onClose: function () {
me.loadingIsClosed = true;
setTimeout(function () {
me.hideLoading();
});
}
});
Api.loading.setProgress(1);
var i = 0;
var total = noteIds.length;
async.eachSeries(noteIds, function (noteId, cb) {
if (me.loadingIsClosed) {
cb();
return;
}
i++;
Api.loading.setProgress(100 * i / total);
Api.noteService.getNote(noteId, function (note) {
me._exportPDF(note, targetPath, function (ok) {
cb();
}, i, total);
});
}, function () {
me.hideLoading();
Notify.show({ title: 'Info', body: getMsg('plugin.export_pdf.exportSuccess') });
});
});
},
_exportPDF: function (note, path, callback, i, total) {
var me = this;
setTimeout(function () {
me._exportPDF(note, path, callback, i, total);
}, 1000);
},
_exportPDF: function (note, path, callback, i, total) {
var me = this;
if (!note) {
return;
}
if (me.loadingIsClosed) {
callback();
return;
}
setTimeout(function () {
Api.loading.setMsg(Api.getMsg('plugin.export_pdf.Exporting: ') + (note.Title || getMsg('Untitled')));
Api.loading.setProgressRate(i + '/' + total);
}, 100);
var name = note.Title ? note.Title + '.pdf' : getMsg('Untitled') + '.pdf';
name = me.fixFilename(name);
var targetPath = path + Api.commonService.getPathSep() + name;
// 将路径和名字区分开
var pathInfo = Api.commonService.splitFile(targetPath);
pathInfo.nameNotExt = me.fixFilename(pathInfo.nameNotExt); // 重新修正一次
var nameNotExt = pathInfo.nameNotExt;
pathInfo.nameNotExtRaw = pathInfo.nameNotExt;
// 得到可用文件的绝对路径
me.getPdfFilePath(pathInfo, 1, function (absPdfFilePath) {
// 得到存放assets的目录
var html = me.render(note);
var tempPath = Api.gui.app.getPath('temp');
var last = tempPath[tempPath.length - 1];
if (last == '/' || last == '\\') {
tempPath = tempPath.substr(0, tempPath.length - 1);
}
var targetHtmlPath = tempPath + '/' + (new Date().getTime()) + '.html';
// 把html文件写到tmp目录
Api.commonService.writeFile(targetHtmlPath, html);
me.exportPdf(targetHtmlPath, absPdfFilePath, note.IsMarkdown, function (args) {
// console.log('export pdf ret');
callback(args.ok);
});
});
},
// 打开前要执行的
onOpen: function () {
var me = this;
var gui = Api.gui;
var menu = {
label: Api.getMsg('plugin.export_pdf.export'),
enabled: function (noteIds) {
return true;
},
click: (function () {
return function (noteIds) {
me.init();
me.exportPDF(noteIds);
}
})()
};
Api.addExportMenu(menu);
Api.addExportMenuForNotebook({
label: Api.getMsg('plugin.export_pdf.export'),
enabled: function (notebookId) {
return true;
},
click: (function () {
return function (notebookId) {
me.init();
me.exportPDFForNotebook(notebookId);
}
})()
});
},
// 打开后
onOpenAfter: function () {
},
// 关闭时需要运行的
onClose: function () {
}
};
return exportPDF;
});