Я пару дней пытался написать веб-приложение для создания текстового документа одним нажатием кнопки.Это то, что я сделал до сих пор:
Структура проекта:
server.js
console.log('Server-side code running');
const express = require('express');
const app = express();
// serve files from the public directory
app.use(express.static('public'));
// serve the homepage
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
client.js
var createDocumentService = require('../services/generateDocumentService.js');
console.log('Client-side code running');
const button = document.getElementById('myButton');
button.addEventListener('click', function(e) {
console.log('button was clicked');
createDocumentService.generateDocument();
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Report Generation</title>
</head>
<body>
<h1>Generate Word Document With a click of a button!</h1>
<button id="myButton">Click me!</button>
</body>
<script src="client.js"></script>
</html>
generateDocumentService.js
var async = require('async')
const officegen = require('officegen')
var fs = require('fs')
var path = require('path')
var generateDocument = function () { //will search for an exact match
console.log('%c%s', 'color: #f2ceb6', 'INSIDE SERVICE GENERATION DOCUMENT');
//var outDir = path.join(__dirname, '../tmp/')
// var themeXml = fs.readFileSync(path.resolve(__dirname, 'themes/testTheme.xml'), 'utf8')
var docx = officegen({
type: 'docx',
orientation: 'portrait',
pageMargins: {
top: 1000,
left: 1000,
bottom: 1000,
right: 1000
}
// The theme support is NOT working yet...
// themeXml: themeXml
})
// Remove this comment in case of debugging Officegen:
// officegen.setVerboseMode ( true )
docx.on('error', function (err) {
console.log(err)
})
pObj = docx.createP({
align: 'center'
})
pObj.addText(' Risk Analysis Report', {
font_face: 'Arial',
font_size: 40
})
//pObj.addLineBreak()
pObj = docx.createP({
backline: 'E0E0E0'
})
pObj.addText('Author: Sami Habboubi', {
bold: true
})
pObj = docx.createP({
backline: 'E0E0E0'
})
pObj.addText('Date: 11/06/2019')
pObj = docx.createP({
align: 'center'
})
pObj.addText('Business Process General Information', {
border: 'dotted',
borderSize: 12,
borderColor: '88CCFF',
bold: true
})
var table = [
[{
opts: {
cellColWidth: 4261,
b: true,
sz: '10',
shd: {
fill: '7F7F7F',
themeFill: 'Arial',
themeFillTint: '20'
},
fontFamily: 'Arial'
}
},
{
opts: {
b: true,
align: 'left',
shd: {
fill: '92CDDC',
themeFill: 'text1',
themeFillTint: '80'
},
fontFamily: 'Avenir Book'
}
}
],
['1. What are your main business objectives? ', 'All grown-ups were once children'],
['2. In which sites(Countries) your team is located?', 'there is no harm in putting off a piece of work until another day.'],
[
'3. What are your key business processes? How are they ranked in terms of criticality?',
'4. But when it is a matter of baobabs, that always means a catastrophe.'
],
['5. What are your main interactions with other Business Lines?', 'watch out for the baobabs!']
]
var tableStyle = {
tableColWidth: 4261,
tableSize: 24,
tableColor: 'ada',
tableAlign: 'left',
tableFontFamily: 'Arial',
}
pObj = docx.createTable(table, tableStyle, )
docx.putPageBreak()
var pObj = docx.createP()
pObj.addText('Simple')
pObj.addText(' with color', {
color: '000088'
})
pObj.addText(' and back color.', {
color: '00ffff',
back: '000088'
})
pObj = docx.createP()
pObj.addText('Since ')
pObj.addText('officegen 0.2.12', {
back: '00ffff',
shdType: 'pct12',
shdColor: 'ff0000'
}) // Use pattern in the background.
pObj.addText(' you can do ')
pObj.addText('more cool ', {
highlight: true
}) // Highlight!
pObj.addText('stuff!', {
highlight: 'darkGreen'
}) // Different highlight color.
pObj = docx.createP()
pObj.addText('Even add ')
pObj.addText('external link', {
link: 'https://github.com'
})
pObj.addText('!')
pObj = docx.createP()
pObj.addText('Bold + underline', {
bold: true,
underline: true
})
pObj = docx.createP({
align: 'center'
})
pObj.addText('Center this text', {
border: 'dotted',
borderSize: 12,
borderColor: '88CCFF'
})
pObj = docx.createP()
pObj.options.align = 'right'
pObj.addText('Align this text to the right.')
pObj = docx.createP()
pObj.addText('Those two lines are in the same paragraph,')
pObj.addLineBreak()
pObj.addText('but they are separated by a line break.')
docx.putPageBreak()
pObj = docx.createP()
pObj.addText('Fonts face only.', {
font_face: 'Arial'
})
pObj.addText(' Fonts face and size.', {
font_face: 'Arial',
font_size: 40
})
docx.putPageBreak()
pObj = docx.createP()
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/image3.png'))
docx.putPageBreak()
pObj = docx.createP()
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/image1.png'))
pObj = docx.createP()
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/sword_001.png'))
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/sword_002.png'))
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/sword_003.png'))
//pObj.addText('... some text here ...', { font_face: 'Arial' })
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/sword_004.png'))
pObj = docx.createP()
//pObj.addImage(path.resolve(__dirname, 'images_for_examples/image1.png'))
docx.putPageBreak()
pObj = docx.createListOfNumbers()
pObj.addText('Option 1')
pObj = docx.createListOfNumbers()
pObj.addText('Option 2')
pObj.addHorizontalLine()
pObj = docx.createP({
backline: 'E0E0E0'
})
pObj.addText('Backline text1')
pObj.addText(' text2')
pObj = docx.createP()
pObj.addText('Strikethrough text', {
strikethrough: true
})
pObj.addText('superscript', {
superscript: true
})
pObj.addText('subscript', {
subscript: true
})
var table = [
[{
val: 'No.',
opts: {
cellColWidth: 4261,
b: true,
sz: '48',
shd: {
fill: '7F7F7F',
themeFill: 'text1',
themeFillTint: '80'
},
fontFamily: 'Avenir Book'
}
},
{
val: 'Title1',
opts: {
b: true,
color: 'A00000',
align: 'left',
shd: {
fill: '92CDDC',
themeFill: 'text1',
themeFillTint: '80'
}
}
},
{
val: 'Title2',
opts: {
align: 'left',
cellColWidth: 42,
b: true,
sz: '48',
shd: {
fill: '92CDDC',
themeFill: 'text1',
themeFillTint: '80'
}
}
}
],
[1, 'All grown-ups were once children', ''],
[2, 'there is no harm in putting off a piece of work until another day.', ''],
[
3,
'But when it is a matter of baobabs, that always means a catastrophe.',
''
],
[4, 'watch out for the baobabs!', 'END']
]
var tableStyle = {
tableColWidth: 4261,
tableSize: 24,
tableColor: 'ada',
tableAlign: 'left',
tableFontFamily: 'Comic Sans MS'
}
pObj = docx.createTable(table, tableStyle)
var out = fs.createWriteStream(path.join('Risk Analysis Report.docx'))
out.on('error', function (err) {
console.log(err)
})
async.parallel(
[
function (done) {
out.on('close', function () {
console.log('Finish to create a DOCX file.')
done(null)
})
docx.generate(out)
}
],
function (err) {
if (err) {
console.log('error: ' + err)
} // Endif.
}
)
}
module.exports.generateDocument = generateDocument;
Что мне нужно:
Использовать метод generateDocument , определенный в generateDocumentService внутри кода кнопки, определенного в client.js :
button.addEventListener('click', function(e) {
console.log('button was clicked');
createDocumentService.generateDocument();
});
Чтобы сделать это, я должен использовать это внутри client.js :
var createDocumentService = require('../services/generateDocumentService.js');
Моя проблема в том, что я не могу использовать require в client.js, потому что это библиотека node.js, поэтому ее нельзя запускать на стороне клиента.
После того, как я провел какое-то исследование, я обнаружил:что я могу использовать webpack, browserfy или require.js для решения этой проблемы.
Но, поскольку метод generateDocument использует модуль fs .Я не думаю, что было бы разумно выставлять файлы для записи и чтения на стороне клиента.
Наконец, вот мои вопросы:
1 / Как правильно вызывать generateDocument метод внутри слушателя события кнопки?Должен ли я использовать webpack, browserfy или require.js?Если нет, то какова альтернатива?
2 / Был ли я прав, когда сказал: Не думаю, что было бы разумно выставлять файлы для записи и чтения на стороне клиента. Надеюсь, я былдостаточно ясно.
Мне действительно нужно достичь этой цели - создать текстовый документ одним нажатием кнопки с помощью officeGen за пару дней.Так что любая помощь горячо приветствуется:))