I have an old Notes Client application. On the form are two RichText fields that hold attachments. JPG's, PDF's, whatever. The document also contains a unique key and other meta-data.
What I want to do is migrate from having multiple attachments on a document to a new document for each attachment. I've never done much with embedded objects and even less with MIME.
I'm currently working in XPages Java but could go to LotusScript if need be.
I was working with this snippet:
List<EmbeddedObject> docPicture = this.getFileAttachments(doc, "picture");
List<EmbeddedObject> docPDF = this.getFileAttachments(doc, "pdf");
for (EmbeddedObject eoPic : docPicture) {
picCount++;
Document newDoc = currentDatabase.createDocument();
newDoc.replaceItemValue("form", "fm_file");
newDoc.replaceItemValue("uploadToken", doc.getItemValueString("barCodeHuman"));
newDoc.replaceItemValue("fileName", eoPic.getName());
newDoc.replaceItemValue("size", eoPic.getFileSize());
fileName = eoPic.getName();
fileType = fileName.substring(fileName.length() - 3);
newDoc.replaceItemValue("type", this.getMIMEType(fileType));
// Extract Attachment and Add To Attachment Document
InputStream attachInputStream = eoPic.getInputStream();
Stream attachStream = session.createStream();
attachStream.setContents(attachInputStream);
MIMEEntity attachField = newDoc.createMIMEEntity("attachment");
MIMEHeader attachHeader = attachField.createHeader("content-disposition");
attachHeader.setHeaderVal("attachment;filename=\"" + eoPic.getName() + "\"");
attachField.setContentFromBytes(attachStream, this.getMIMEType(fileType), MIMEEntity.ENC_IDENTITY_BINARY);
Note I'm using the OpenNTF API but could go back to the lotus objects if need be.
Anyway - this almost worked. I got my documents - 1 per attachment. But when going into the field "attachment" in the document propertied it's not a RichTextField it's a MIME something. that's causing me probably with the next phase of my project. The RichTextDocuments work fine but not the MIME ones.
this is a 1 time migration need so any thoughts on how I can end up with RichTextFields would be appreciated. Thanks!!
try to not involve mime entities at all.
as Oliver said, check your target richText field on the form does not have the 'store contents as mime' checked.
you could even use a richText lite field and restrict it to attachments.
I think you might be using the MIMEEntity method setContentsFromStream because you want to directly move the attachment from doc to doc?
if you want to move using just RichText embedded objects (no mime entity involvement) you need to extract the embeddedObject using .extractFile to the file system first.
Then using the RichTextItem that you create on the new doc (instead of create mime entity) you can use rti.embedObject to attach the file you extracted. (probably best to delete the temporary extract file after successful migration), see the designer help for an example of the parameters required for embedding attachments.
when extracting the file to file system you could extract it to the JVM's temporary directory, the file on the file system needs to have the same file name that you want it to have when attached to the new document.
for this reason you can't really use File.createTemporaryFile() because your temp file name will have random characters in it. instead you
you can get the temp directory with
System.getProperty("java.io.tmpdir")`
and the use that in your extract filepath.
another thing to check before starting processing, is the current notesSession's isConvertMIME setting, if to source field is mime, session.isConvertMIME == true will convert the field to richText when loading the doc. I think in xpages it is false by default, though I don't think it will affect you because I think your source attachments are already richText but for someone reading this and using mime source field it would be important to note. also if you change this using setConvertMIME, be sure to change it back to what it was when you finish your processing.
Related
What is the best way to send docusign contracts in a way that allows them to be editable during the envelope creation process?
See in DocuSign Documentation, we can see how to create documents and then attach them to the envelope:
docPdfBytes = fs.readFileSync(path.resolve('demoDocsPath', 'pdf1File.pdf'));
// add the documents
let doc1 = new docusign.Document()
, doc1b64 = Buffer.from(docPdfBytes).toString('base64')
;
doc1.documentBase64 = doc1b64;
doc1.name = 'Lorem Ipsum'; // can be different from actual file name
doc1.fileExtension = 'pdf';
doc1.documentId = '3';
An alternative that I found and that allows you to send a document where it is possible to make 'replaces' to fill in things like "name, address" is to save HTML in a string, instead of a pure PDF.
Docusign requires you to convert my file to base64, which will be transformed at the end of the request into a final PDF with the docusign configuration. The problem is when there are images in the HTML file, during HTML conversion -> 64 -> PDF, the images are not treated in a faithful way, for example, when there is a watermark, the PDF returns a page with the watermark and the misaligned body, see the example: expected and what i have.
Is there a better way to send replaceable documents? If not, how can you force the final PDF to respect CSS properties?
There are several techniques for creating custom documents. See my SO Answer
With regards to your question:
Base64 is an encoding technique. It has zero impact on the document.
The real issue you're facing is that the DocuSign conversion from HTML to PDF is not as sophisticated as your use case needs. For these types of use cases, I recommend that you create the PDF yourself.
There are many PDF creation libraries that enable your software to create exactly the PDF that you want.
If you only need to customize a form, you can use DocuSign tags (fields) to hold the dynamic data. Your application can set tags to have values from your data and either allow or not allow the document recipients to change the data as part of the signing process.
You can use an HTML original to specify the tags (see my other answer), or you can add the tags to your PDF document. Best is to use anchor text for that.
I followed this link enabling me to setup a hotspot in a richtext field - works like charm.
http://ozinisle.blogspot.de/2010/11/lotusscript-code-to-append-hotspot-to.html
Only problem is, as the user(s) usually do(es) not have deletion rights, the document created by the import stays stored in the database. In LotusScript e.g. I can create a new temporary document and work with it, and if I'm not saving it, it just disappears at the end of the function.
Is there a similar way or parameter for DXL import which allows me to just drop the document after I got my rtitem?
Alternatively, can someone point out to me if it is possible to create only the temporary richtext item in/on a document I created as tempdoc via LotusScript?
My search on the web did not get any results and my tries to reduce the linked function always resulted in the error 4518 (which is described in the help document of "DXLImporter"); if I read the help right, the DXLImporter only supports the db as valid output (thus expecting documents being created via DXL).
I don't see a way to import DXL without creating a document.
The easiest solution is to create the temporary document in users "cache.ndk". The user has definitely the right to delete documents there. So, you'd replace the line "Set db = session.CurrentDatabase" in code you linked to with
Set db = session.Getdatabase("", "cache.ndk", false)
The rest of the code would stay the same.
As an alternative, use the more classic approach running an agent on server to delete the temporary document. Create an agent which deletes the document, set property "Run on behalf of" to someone who is allowed to delete documents in database and call the agent from your script with
agent.RunOnServer(noteID)
I am able to add a file upload control to my page and add attachments. But how do I manage them? View , delete?
I added a computed field to my xpage and make the attachments field the source and set the field as HTML. I get a bunch of entries like (See attached file: abc.pdf). But that does not seem to do what I want.
Is there an easy way to manage these attached files?
Bind a file download control to the same data the upload control is bound to. One of the attributes this component supports is a boolean for whether to allow deletion. You can also choose which attributes of each file it displays (MIME type, size, etc.).
What is wrong with having an repeat control repeat over the filenames and generate links directly to those files where on the links there are event handlers which do a remove or view ?
I'm going to make a document library with SharePoint 2010. I'm handling files that would be updated frequently and many meta data fields such as update frequency, filtering flag, monitoring flag, etc.
If SharePoint stores the files in the database, I think, it's possible to update the file content field alone without touching other fields containing meta data. But apparently it's not easy at the first glance.
Any simple way to update document content in the MOSS environment? I guess that check-out the file and update or edit then check-in is a possible solution but requires too much works for the end users.
You could disable check-in/check-out on the document library
Or you could do something like this in a web part
SPFile file = web.GetFile(url);
file.UndoCheckOut();
string rawdata = Path.Combine(rootdirectory, url);
byte[] data = File.ReadAllBytes(rawdata);
file.CheckOut();
file.SaveBinary(data);
file.Update();
file.CheckIn("some thing");
file.Approve("some thing");
I have a content type that has required fields. I have associated Word document with the content type as a template. I now want to edit the Word template, but word won't allow me to save the template without filling in the required fields. However, if I fill in the required fields and save the document, then those fields get populated with my values when you create a new document. This isn't good because I want the fields to be blank when a new document is created - I want the users to be forced to fill in those values.
I can update the templace by updating the colums and making them optional, editing the word template, saving the template & then changing the columns back to required. This is a PITA - there's got to be a better way, does anyone know what it is?
I've been using this work around: When I edit the template (ie go to the content type settings --> Advanced settings --> Edit Template), I make my changes and save the file locally. Then, on the same page that I clicked the "Edit Template" link, I upload the copy that I saved locally. Saving it locally avoids the validation that happens when you try to save it back to SharePoint. But the validation still gets applied to any new documents of that content type. So no need to toggle the settings off & on! :)
Have you tried saving the document as a normal document content type, making the changes, saving it, then moving back over the top of where the old version of the template was?
The only solution I've found is to modify document templates on library level. Just upload a new document template for the required content type.
However, this will not work if you'd like to re-use one and same content type across different document libraries.