nodejs npm libraries to access and modify microsoft word documents - pdf

Do you know if it is possible to search specific text like "xAx" into a Microsoft Word file (.doc or .docx) hosted on a website, replace it with some other text input by the user and make the file available for download using nodejs?
Is there a npm library that can do that?
If not it is possible to manipulate a PDF file instead? Please note that I do not want to create the document but manipulate a template file in the server.
Thank you for your help.

There is project https://github.com/open-xml-templating/docxtemplater which serves for replacing {placeholders} in a .docx files.
Also supports loops and images, check out demo (examples) on http://javascript-ninja.fr/docxtemplater/v1/examples/demo.html

If odt is an option (these files are open directly by MS Word besides Open and Libre Office and can be set with extension .doc so end users do not freak out) you can use HTML52PDF.
For example something like the following code will replace a string of text by a link:
require_once 'path/to/CreateDocument.inc';
$doc = new Html52pdf\createDocument(array('template' => 'template.odt'));
$format = '.odt';//.pdf, .doc, .docx, .odt, .rtf
//replace natural text
$doc->replace(array('replace me, please' => array('value' => 'external link')), array('format' => array('','')));
$doc->render('replaced_content' . $format);

Related

How to access pdf file outside of public_html in joomla site?

Actually i want to edit a module to fetch PDF file outside from public_html.
I already tried to change permission of that file from which i want to fetch PDF to 777.
I am trying to fetch PDF by following codes
$baseurl = JURI::base();
$outside_baseurl = $baseurl.'../pdf/name.pdf';
Shows this error
Cannot access file!
https://mysitedomain.com/../pdf/name.pdf
It's really not safe to access a file outside the scope of your public folder in the open like that. It has the potential to open serious security holes. If you are trying to do this to modify or use the PDF file for something inside PHP, you should be able to. If you are trying to send it to a user for download or preview, you might wanna try fpassthru(). Something like the example below.
<?php
$path = 'path/to/file.pdf';
$public_name = basename($path);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $path);
header("Content-Disposition: attachment; filename=$public_name;");
header("Content-Type: $mime_type");
header('Content-Length: ' . filesize($path));
$fop = fopen($path, 'rb');
fpassthru($fop);
exit;
This should serve your purpose.

How to decode URL entities in iMacros URL extraction?

I write some infos with the current URL into a csv-file with imacros. The URLs are written with
ADD !EXTRACT {{!URLCURRENT}}
SAVEAS TYPE=EXTRACT FOLDER=* FILE=+{{!NOW:ddmmyyyy}}.csv
After i open the csv file in Excel (open an empty Excel file, then import data from text (my csv) file) everything is OK, but if there are any entities in the URL, they are encoded like https://www.google.de/search?q=g%C3%83%C2%BCnstig%20%C3%83%C2%BCbernachten.
How can i adjust the iMacros code to write URLs and /or save the csv file with decoded URL entities?
I guess it could be possible to run something like decodeURIComponent or even something like this inside of iMacros, but don't know the right syntax for such implementations. My try to replace
ADD !EXTRACT {{!URLCURRENT}}
with
SET !VAR2 decodeURIComponent ({{!URLCURRENT}})
ADD !EXTRACT {{!VAR2}}
or
SET !VAR2 unescape ({{!URLCURRENT}})
ADD !EXTRACT {{!VAR2}}
don't work:(
This seems to work:
SET !EXTRACT {{!URLCURRENT}}
SET !EXTRACT EVAL("decodeURI('{{!EXTRACT}}');")
SAVEAS TYPE=EXTRACT FOLDER=* FILE=+{{!NOW:ddmmyyyy}}.csv
(However Microsoft Excel may not support UTF-8 encoding. So, open it with something like ‘Notepad’.)

How to ForceDownload a file in OPENERP

I'm generating a pdf and storing it on my server using Openerp.Can any one please tell me how to Force Download that file using Openerp.If can upload the pdf using fields.binary and download it automatically.But i don't want to store the file in database.I want to directly download it.Can any one help me.Thanks in advance
I solved the issue by installing "Document Management System" module and attaching the files to "ir.attachment" instead of storing them as a binary field.Now you can download the document from the attachments.
code :
filename="/home/cryosave_qrcodes/xyz.pdf"
files = open(filename,'rb').read().encode('base64')
ir_values={
'name':image_name,
'datas_fname': image_name,
'type':'binary',
'datas':files,
'create_uid':uid,
'partner_id':ids[0],
'res_model':'res.partner',
'res_id':ids[0],
}
self.pool.get('ir.attachment').create(cr,uid,ir_values,context=context)
Fetch what file you want
use read and write function in python.
import os
path = os.path.join(os.path.expanduser(),('~'), 'documents', 'python', 'file.txt')
fh = open(path,"w")
fh.write("Hello World")
fh.close()

How can I allow more file extensions with drupal file uploads?

I've got a module that has to let users upload files and everything works as long as the files are in the standard array of allowed extensions. I've tried using file_validate_extensions, but this doesn't seem to change anything.
This is the code I'm using to upload now (the docx extension is added to the standard drupal allowed ones, but it doesn't seem to get picked up):
$fid = $form_state['values']['attachment'];
$file = file_load($fid);
if($file != null){
file_validate_extensions($file, "jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp docx");
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
I just looked to this Drupal API, and it seems that you can use the function "file_save_upload" (with $validator as an array of valid extension), this get the file in a temporary state. And then, you have to call "file_save" to make it permanent.

How to do mail merge on top of a PDF?

I often get a PDF from our designer (built in Adobe InDesign) which is supposed to be sent out to thousands of people.
I've got the list with all the people, and it's easy doing a mail merge in OpenOffice.org. However, OpenOffice.org doesn't support the advanced PDF. I just want to output some text onto each page and print it out.
Here's how I do it now: print out 6.000 copies of the PDF, then put all of them into the printer again and just print out name, address and other information on top of it. But that's expensive.
Sadly, I can't make the PDF to an image and use that in OpenOffice.org because it grinds the computer to a halt. It also takes extremely long time to send this job to the printer.
So, is there an easy way to do this mail merge (preferably in Python) without paying for third party closed solutions?
Now I've made an account. I fixed it by using the ingenious pdftk.
In my quest I totally overlook the feature "background" and "overlay". My solution was this:
pdftk names.pdf background boat_background.pdf output out.pdf
Creating the names.pdf you can easily do with Python reportlab or similar PDF-creation scripts. It's best using code to do that, creating 6k pages took several hours in LibreOffice/OpenOffice, while it took just a few seconds using Python.
You could probably look at a PDF library like iText. If you have some programming knowledge and a bit of time you could write some code that adds the contact information to the PDFs
There are two much simpler and cheaper solutions.
First, you can do your mail merge directly in InDesign using DataMerge. This is a utility added to InDesign way back in CS. You export or save your names in CSV format. Import the data into an InDesign template and then drop in your name, address and such fields in the layout. Press Go. It will create a new document with all the finished letters or you can go right to the printer.
OR, you can export your data to an XML file and create a dynamic layout using XML placeholders in InDesign.
The book A Designer's Guide to Adobe InDesign and XML will teach you how to do this, or you can check out the Lynda.com videos for Dynamic workflows with InDesign and XML.
Very easy to do.
If you want to create separate PDFs files for the mail merge, you can run out one long PDF with all the names in one file then do an Extract to Separate PDF files in Acrobat Pro itself.
If you cannot get the template in another format than PDF a simple ad-hoc solution would be to
convert the PDF into an image
put the image in the backgroud of your (OpenOffice.org) document
position mail merge fields on top of the image
do the mail merge and print
Probably the best way would be to generate another PDF with the missing text, and overlay one PDF over the other. A quick Google found this link showing how to do it in Acrobat, and I'm sure there are other methods as well.
http://forums.macrumors.com/showthread.php?t=508226
For a no-mess, no-fuss solution, use iText to simply add the text to the pdf. For example, you can do the following to add text to a pdf document once loaded:
PdfContentByte cb= ...;
cb.BeginText();
cb.SetFontAndSize(font, fontSize);
float x = ...;
float y = ...;
cb.SetTextMatrix(x, y);
cb.ShowText(fieldValue);
cb.EndText();
From there on, save it as a different file, and print it.
However, I've found that form fields are the way to go with pdf document generation from templates.
If you have a template with form fields (added with Adobe Acrobat), you have one of two choices :
Create a FDF file, which is essentially a list of values for the fields on the form. A FDF is a simple text document which references the original document so that when you open up the PDF, the document loads with the field values supplied by the FDF.
Alternatively, load the template with with a library like iText / iTextSharp, fill the form fields manually, and save it as a seperate pdf.
A sample FDF file looks like this (stolen from Planet PDF) :
%FDF-1.2
%âãÏÓ
1 0 obj
<<<
/F(Example PDF Form.pdf)
/Fields[
<<
/T(myTextField)
/V(myTextField default value)
>>
]
>>
>> endobj trailer
<>
%%EOF
Because of the simple format and the small size of the FDF, this is the preferred approach, and the approach should work well in any language.
As for filling the fields programmatically, you can use iText in the following way :
PdfAcroForm acroForm = writer.AcroForm;
acroForm.Put(new PdfName(fieldInfo.Name), new PdfString(fieldInfo.Value));
What about using a variable data program such as - XMPie for Adobe Indesign. It's a plug-in that should reference to your list of people (think it might have to be a list in Excel though).
One easy way would be to create a fillable pdf form from the original document in Acrobat and do a mail merge with the form and a csv.
PDF mail merges are relatively easy to do in python and pdftk. Fdfgen (pip install fdfgen) is a python library that will create an fdf from a python array, so you can save the excel grid to a csv, make sure that the csv headers match the name of the pdf form field you want to fill with that column, and do something like
import csv
import subprocess
from fdfgen import forge_fdf
PDF_FORM = 'path/to/form.pdf'
CSV_DATA = 'path/to/data.csv'
infile = open(CSV_DATA, 'rb')
reader = csv.DictReader(infile)
rows = [row for row in reader]
infile.close()
for row in rows:
# Create fdf
filename = row['filename'] # Construct filename
fdf_data = [(k,v) for k, v in row.items()]
fdf = forge_fdf(fdf_data_strings=fdf_data)
fdf_file = open(filename+'.fdf', 'wb')
fdf_file.write(fdf)
fdf_file.close()
# Use PDFTK to create filled, flattened, pdf file
cmds = ['pdftk', PDF_FORM, 'fill_form', filename+'.fdf',
'output', filename+'.pdf', 'flatten', 'dont_ask']
process = subprocess.Popen(cmds, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
returncode = process.poll()
os.remove(filename+'.fdf')
I've encountered this problem enough to write my own free solution, PdfZero. PdfZero has a mail merge feature to merge spreadsheets with PDF forms. You will still need to create a PDF form, but you can upload the form and csv to pdfzero, select which form fields you want filled with which columns, create a naming convention for each filled pdf using the csv data if needed, and batch generate the filled PDfs.
DISCLAIMER: I wrote PdfZero
Someone asked for specifics. I didn't want to sully my top answer with it, because you can do it how you like (and just knowing pdftk is up to it should give people the idea).
But here's some scripts I used ages ago:
csv_to_pdf.py
#!/usr/bin/python
# This makes one PDF page per name in the CSV file
# csv_to_pdf.py <CSV_FILE>
import csv
import sys
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.units import cm, mm
in_db = csv.reader(open(sys.argv[1], "rb"));
outname = sys.argv[1].replace("csv", "pdf")
pdf = Canvas(outname)
in_db.next()
i = 0
for rad in in_db:
pdf.setFontSize(11)
adr = rad[1]
tekst = pdf.beginText(2*cm, 26*cm)
for a in adr.split('\n'):
if not a.strip():
continue
if a[-1] == ',':
a = a[:-1]
tekst.textLine(a)
pdf.drawText(tekst)
pdf.showPage()
i += 1
if i % 1000 == 0:
print i
pdf.save()
When you've ran this, you have a file with thousands of pages, only with a name on it. This is when you can background the fancy PDF under all of them:
pdftk <YOUR_NEW_PDF_FILE.pdf> background <DESIGNED_FILE.pdf> <MERGED.pdf>
You can use InDesign's data merge function, or you can do what you've been doing with printing a portion of the job, and then printing the mail merge atop that with Word or Open Office.
But also look into finding a company that can do variable data offset printing or dynamic publishing. Might be a little more expensive up front but can save a bundle when it comes to time, testing, even packaging and mailing.
Disclaimer: I'm the author of this tool.
I ran into this issue enough times that I built a free online tool for it: https://pdfbatchfill.com/
It assumes a PDF form as a template and uses that along with CSV form data to generate a single PDF or individual PDFs in a zip file.