I have a form with some text fields and I also needed to send attachments within same form.
Form is printed by agent and is processed by another agent written in LotusScript.
I spent some time working on solution and here it is.
The idea is to convert selected files to base64 on client side and then post data on submission and agent that process submission will conver base64 to file.
Here is a form, note that we run some logic when files are added
<form name="formName" method="post" action="agentName?openagent">
<input name="title" value="xxx">
<input type="file" name="files" multiple onchange="toBase64()">
</form>
Here is how we convert selected files to base64 and how we results as text fields to form (JS is not optimal, it can be done without jQuery)
function toBase64() {
var files = document.querySelector('input[type=file]').files;
var form = $("form");
form.find("input[name^='filebase64']").remove(); // replace
function readAndSave(file, index) {
var reader = new FileReader();
reader.addEventListener("load", function() {
form.append("");
form.append("");
}, false);
reader.readAsDataURL(file);
}
if (files) {
[].forEach.call(files, readAndSave);
}
}
Once form is submitted we have to read base64 items and convert them to file. There are at least 2 solutions: pure LS or Java/LS2J
a) LotusScript using NotesMIMEHeaderPrivate Function saveBase64AsFile(base64 As String, filePath As string) As Boolean
On Error GoTo ErrorHandler
Dim stub As NotesDocument
Dim stream As NotesStream
Dim item As NotesMIMEEntity
Dim header As NotesMIMEHeader
Dim emb As NotesEmbeddedObject
Dim fileName As String
Dim contentType As string
Dim base64File As String
fileName = StrRightBack(filePath, "\")
contentType = StrRight(Strleft(base64, ";"), ":")
base64File = StrRight(Base64, ",")
Call scriptLog.loginfo(fileName)
Call scriptLog.loginfo(contentType)
Set stub = db.Createdocument()
Set item = stub.CreateMIMEEntity("Body")
Set header = item.createHeader("Content-Disposition")
Call header.setHeaderVal({attachment; filename="} & fileName & {"})
Set stream = app.NotesSession.CreateStream()
Call stream.WriteText(base64File)
Call item.SetContentFromText(stream, contentType, ENC_BASE64)
Call stream.Truncate
Call stream.Close
Call stub.Closemimeentities(True)
Set emb = stub.Getattachment(fileName)
Call emb.Extractfile(filePath)
Exit Function
ErrorHandler:
Error Err, Error
End Function
b) Java with LS2J using native classses.
import java.util.Base64;
import java.io.IOException;
import java.nio.file.*;
public class Base64ToFile{
public boolean convert(String base64String, String filePath) {
try {
byte[] decodedImg = Base64.getDecoder().decode(base64String.getBytes());
Path destinationFile = Paths.get(filePath);
Files.write(destinationFile, decodedImg);
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
UseLSX "*javacon"
Use "Base64ToFile"
Class Base64ToFile
Private jSession As JavaSession
Private jClass As Javaclass
Private jObject As JavaObject
Private jError As JavaError
Sub New()
Set jSession = New JavaSession
Set jClass = jSession.GetClass("Base64ToFile")
Set jObject = jClass.Createobject()
End Sub
Public Function convert(base64 As String, filePath As String) As Boolean
convert = jObject.convert(base64, filePath)
End Function
End Class