Je stocke des fichiers Word (.docx) en utilisant GridFS sur le serveur. J'aimerais pouvoir fusionner les documents dans un fichier Word en utilisant le package NPM docx-builder.Comment exécuter les opérations de gestion de fichiers côté serveur dans Meteor?
Voilà comment je télécharger les fichiers:
Meteor.methods({
uploadFiles: function (files) {
check(files, [Object]);
if (files.length < 1)
throw new Meteor.Error("invalid-files", "No files were uploaded");
var documentPaths = [];
_.each(files, function (file) {
ActivityFiles.insert(file, function (error, fileObj) {
if (error) {
console.log("Could not upload file");
} else {
documentPaths.push("/cfs/files/activities/" + fileObj._id);
}
});
});
return documentPaths;
}
})
Comment puis-je aller sur le faire sur le côté serveur? Je ne peux faire ce côté serveur que parce que le paquet que j'utilise nécessite le paquet fs
qui ne peut pas être exécuté côté client.
Voici comment j'essaie de travailler sur ce sujet pour le moment. À partir du client, j'appelle la méthode suivante (qui est déclarée comme Meteor.method
):
print: function(programId) {
// Get the program by ID.
var program = Programs.findOne(programId);
// Create a new document.
var docx = new docxbuilder.Document();
// Go through all activities in the program.
program.activityIds.forEach(function(activityId) {
// Create a temporary server side folder to store activity files.
const tempDir = fs.mkdtempSync('/tmp/');
// Get the activity by ID.
var activity = Activities.findOne(activityId);
// Get the document by ID.
var document = ActivityFiles.findOne(activity.documents.pop()._id);
// Declare file path to where file will be read.
const filePath = tempDir + sep + document.name();
// Create stream to write to path.
const fileStream = fs.createWriteStream(filePath);
// Read from document, write to file.
document.createReadStream().pipe(fileStream);
// Insert into final document when finished writinf to file.
fileStream.on('finish',() => {
docx.insertDocxSync(filePath);
// Delete file when operation is completed.
fs.unlinkSync(filePath);
});
});
// Save the merged document.
docx.save('/tmp' + sep + 'output.docx', function (error) {
if (error) {
console.log(error);
}
// Insert into Collection so client can access merged document.
Fiber = Npm.require('fibers');
Fiber(function() {
ProgramFiles.insert('/tmp' + sep + 'output.docx');
}).run();
});
}
Cependant, quand je télécharge le document final de la collection ProgramFiles
du côté client, le document est un Vider le document Word.
Qu'est-ce qui ne va pas ici?
J'ai incorporé la réponse @ FrederickStark dans mon code. Juste coincé sur cette partie maintenant.
Voici un autre essai:
'click .merge-icon': (e) => {
var programId = Router.current().url.split('/').pop();
var programObj = Programs.findOne(programId);
var insertedDocuments = [];
programObj.activityIds.forEach(function(activityId) {
var activityObj = Activities.findOne(activityId);
var documentObj = ActivityFiles.findOne(activityObj.documents.pop()._id);
JSZipUtils.getBinaryContent(documentObj.url(), callback);
function callback(error, content) {
var zip = new JSZip(content);
var doc = new Docxtemplater().loadZip(zip);
var xml = zip.files[doc.fileTypeConfig.textPath].asText();
xml = xml.substring(xml.indexOf("<w:body>") + 8);
xml = xml.substring(0, xml.indexOf("</w:body>"));
xml = xml.substring(0, xml.indexOf("<w:sectPr"));
insertedDocuments.push(xml);
}
});
JSZipUtils.getBinaryContent('/assets/template.docx', callback);
function callback(error, content) {
var zip = new JSZip(content);
var doc = new Docxtemplater().loadZip(zip);
console.log(doc);
setData(doc);
}
function setData(doc) {
doc.setData({
// Insert blank line between contents.
inserted_docs_formatted: insertedDocuments.join('<w:br/><w:br/>')
// The template file must use a `{@inserted_docs_formatted}` placeholder
// that will be replaced by the above value.
});
doc.render();
useResult(doc);
}
function useResult(doc) {
var out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
saveAs(out, 'output.docx');
}
ce que vous avez essayé jusqu'à présent? Vous devriez juste être en mesure d'interroger les fichiers de la base de données et les transmettre dans docx-builder –
@FrederickStark J'ai ajouté mon travail. –