Poi4Xpages - write file to document during postGeneration - apache-poi

as per a suggestion recently received from Stwissel, I am using the following code to convert a file to mime and attach to a notes document during the post generation process of POI4Xpages.
EDITED NEW CODE:
The following code attaches to document, but throws an error: 502 Bad Gateway - The server returned an invalid or incomplete response.
public void saveExcel(Workbook a, Document newDoc) throws NotesException, IOException{
newDoc.replaceItemValue("Form", "Provider");
// Create the stream
Session session = DominoUtils.getCurrentSession();
Stream stream = session.createStream();
// Write the workbook to a ByteArrayOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
a.write(bos);
// Convert the output stream to an input stream
InputStream is = new ByteArrayInputStream(bos.toByteArray());
stream.setContents(is);
MIMEEntity m = newDoc.createMIMEEntity("body");
MIMEHeader header = m.createHeader("content-disposition");
header.setHeaderVal("Mime attachment");
m.setContentFromBytes(stream, "application/vnd.ms-excel", MIMEEntity.ENC_IDENTITY_BINARY);
m.decodeContent();
newDoc.save(true, true);
}
ORIGINAL CODE:
var stream:NotesStream = session.createStream();
// Do not automatically convert MIME to rich text
session.setConvertMIME(false);
var doc:NotesDocument = database.createDocument();
doc.replaceItemValue("Form", "Provider");
var body:NotesMIMEEntity = doc.createMIMEEntity();
var header:NotesMIMEHeader = body.createHeader("Subject");
header.setHeaderVal("MIME attachment");
if (stream.open("c:\\notes\\data\\abc.xlsx", "binary")) {
if (stream.getBytes() != 0) {
body.setContentFromBytes(stream, "application/vnd.ms-excel",
NotesMIMEEntity.ENC_IDENTITY_BINARY);
} else requestScope.status = "File was not found.";
} else requestScope.status = "Could not open file.";
stream.close();
doc.save(true, true);
// Restore conversion
session.setConvertMIME(true);
However, this code is only attaching a file which is already stored on the server's local directory. How can I get this code to take the POI fileOutputStream and attach that?

It's a mix of what what Knut and I've commented about. The important part is that you'll use the write() method to pass the workbook data to an output stream.
// Create the stream
Stream stream = session.createStream();
// Write the workbook (you haven't clarified) to a ByteArrayOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
// Convert the output stream to an input stream
InputStream is = new ByteArrayInputStream(bos.toByteArray());
stream.setContents(is);

Related

send compressed message using avro

I have a POJO which in need to send to another end-poind (some server).
I have decided it do it using avro.
So far I have created my Avro schema and generated my DataFileWriter:
GenericRecord user1 = new GenericData.Record(schema);
user1.put("name", "Jenny");
user1.put("favorite_color", "green");
GenericRecord user2 = new GenericData.Record(schema);
user2.put("name", "Kevin");
user2.put("favorite_color", "red");
DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(datumWriter);
dataFileWriter.create(schema, schemaFile);
dataFileWriter.append(user1);
dataFileWriter.append(user2);
This is what I have so far and I'm missing the following:
I would like to compress the data before sending it, I rather doing it using snappy, how should I combine it with my code?
UPDATE:
Added these lines:
// use snappy compression
CodecFactory codecFactory = CodecFactory.snappyCodec();
dataFileWriter.setCodec(codecFactory);
But I'm not sure yet if it does the job.
Using this:
public byte[] serialize(T objectToSerialize) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DatumWriter<T> reflectDatumWriter = new ReflectDatumWriter<T>(avroSchema);
DataFileWriter<T> fileWriter = null;
try {
fileWriter = new DataFileWriter<T>(reflectDatumWriter);
fileWriter.setCodec(CodecFactory.snappyCodec());
fileWriter.create(avroSchema, out);
fileWriter.append(objectToSerialize);
fileWriter.close();
} catch (Exception e) {
LOG.error(e);
return null;
}
return out.toByteArray();
}

How to get isolated storage image as stream?

I have very uncommon problem. firstly let me tell you that i want to build a WP8 apps about images. I have some images stored in the project solution and using those for the apps and it is working fine.
i am using one
public Stream ImageStream
{
get
{
return this.imageStream;
}
set
{
this.imageStream = value;
}
}
Now for the project solution images this Image stream i am calling like this
StreamResourceInfo imageRes = Application.GetResourceStream(new Uri("WindowsPhone;component/Images/Image1.jpg", UriKind.Relative));
this.ImageStream = imageRes.Stream;
Now the problem begins if I try to use any image from media library. I can store the file into Isolated storage and from their I can access the file. What I am doing is
using (IsolatedStorageFile Iso = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = new IsolatedStorageFileStream(strFileName, FileMode.Open, FileAccess.Read, Iso))
{
IsolatedStorageFileStream fileStream = Iso.OpenFile(strFileName, FileMode.Open, FileAccess.Read);
data = new byte[stream.Length];
// Read the entire file and then close it
stream.Read(data, 0, data.Length);
stream.Close();
}
}
MemoryStream ms = new MemoryStream(data);
BitmapImage bi = new BitmapImage();
// Set bitmap source to memory stream
bi.SetSource(ms);
However i can use the image file and can show but you can see it is a bit map image, and as it is in isolated storage I can not use
StreamResourceInfo imageRes ...
this.ImageStream = ...
Any help how can I use this.ImageSteam Properties? any other ideas will be welcome. I am actually beginner in WP8 programming
Or Let me ask you a simple Question how can I read a image which is in isolatedstorage to StreamResourceInfo ?
If I can do that my problem is solved. please help me.
*Save Image to Isolated Storage: *
String tempJPEG = "logo.jpg";
// Create virtual store and file stream. Check for duplicate tempJPEG files.
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
//wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
Happy Coding...
why execute a stream copy ?
http://www.windowsphonegeek.com/tips/All-about-WP7-Isolated-Storage---Read-and-Save-Images
try something like
BitmapImage bi = new BitmapImage();
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile("logo.jpg", FileMode.Open, FileAccess.Read))
{
bi.SetSource(fileStream);
this.img.Height = bi.PixelHeight;
this.img.Width = bi.PixelWidth;
}
}
this.img.Source = bi;

Create a copy of an InputStream from an HttpURLConnection so it can be used twice

I used this question
How do I convert an InputStream to a String in Java?
to convert an InputStream to a String with this code:
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
My inputstream comes from an HttpURLConnection InputStream, and when I do my conversion to String, the inputstream changes and I cannot longer use it. This is the error that I get:
Premature end of file.' SOAP
What can I do to keep my inputstream, when I convert it to string with the proper information?.
Speciffically this is the information that changes:
inCache = true (before false)
keepAliveConnections = 4 (before 5)
keepingAlive = false (before true)
poster = null (before it was PosterOutputStream object with values)
Thank you.
If you pass your input stream into scanner or read its data in any other way. you actually consuming its data and there will be no available data in that stream anymore.
you may need to create a new input stream with same data and use it instead of the original one. for example:
ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
// inputStream is your original stream.
for (int n; 0 < (n = inputStream.read(buf));) {
into.write(buf, 0, n);
}
into.close();
byte[] data = into.toByteArray();
//This is your data in string format.
String stringData = new String(data, "UTF-8"); // Or whatever encoding
//This is the new stream that you can pass it to other code and use its data.
ByteArrayInputStream newStream = new ByteArrayInputStream(data);
The scanner reads till the end of the stream and closes it. So it will not be available further. Use PushbackInputStream as a wrapper to your input stream and use the unread() method.
Try to Use Apache Utilities.
In my preset project, I have done the same thing
InputStream xml = connection.getInputStream();
String responseData = IOUtils.toString(xml);
You can get IOUtils from Apache [import org.apache.commons.io.IOUtils]

Sending OutputStream to browser and let browser save it [duplicate]

This question already has answers here:
How to provide a file download from a JSF backing bean?
(5 answers)
Closed 7 years ago.
I want to export Data from a Rich Faces Data Table I have created outputStream from the data in the Data Table. Now want to send this OutputStream to browser and let it save. How can I do this?
FileOutputStream stream = new FileOutputStream(new File(PATH));
OutputStream out = myMthodToCreateOutPutStream();
Now how to save this out to browser .
It's not clear where you are reading your data from. You need to create an InputStream to read the data.
Then, you first need to set the response headers to
HttpServletResponse.setHeader("Content-Disposition", "attachment; filename=datafile.xls");
Use whatever filename you need.
Then set the mime-type:
response.setContentType("application/vnd.ms-excel");
Use the mime-type you need.
Then need to use the response object to get its outputstream -
OutputStream outStream = response.getOutputStream();
Now write to it:
byte[] buf = new byte[4096];
int len = -1;
//Write the file contents to the servlet response
//Using a buffer of 4kb (configurable). This can be
//optimized based on web server and app server
//properties
while ((len = inStream.read(buf)) != -1) {
outStream.write(buf, 0, len);
}
outStream.flush();
outStream.close();

Merge memorystreams to one iText document

I have four MemoryStreams of data that I want to merge and then open the pdfDocument, without creating a single file.
It's possible to write them down to files and then merge them but that would be bad practice and that can also cause a few issues so I want to avoid that.
However, I can not find a way to merge the MemoryStreams with iText5 for .NET.
Right now, this is how I do it with files:
private static void ConcatenateDocuments()
{
var stream = new MemoryStream();
var readerFrontPage = new PdfReader(Folder + FrontPageName);
var readerDocA = new PdfReader(Folder + docA);
var readerDocB = new PdfReader(Folder + DocB);
var readerAppendix = new PdfReader(Folder + Appendix);
var pdfCopyFields = new PdfCopyFields(stream);
pdfCopyFields.AddDocument(readerFrontPage);
pdfCopyFields.AddDocument(readerDocA );
pdfCopyFields.AddDocument(readerDocB);
pdfCopyFields.AddDocument(readerAppendix);
pdfCopyFields.Close();
SavePdf(stream, FilenameReport);
}
Since I need to remove the use of files, I keep the MemoryStream's as the different parts are built from different resources. So I have references to these memorystreams.
How can this be done?
The error PDF header signature not found can be fixed in this case by setting the stream's Position back to 0. Since you're not getting the error Cannot access a closed Stream I'm assuming that you are already correctly setting the PdfWriter's CloseStream to false.
Below is a full working C# 2010 WinForm app targeting iTextSharp 5.1.1.0 that creates three PDFs in MemoryStreams and combines them. Since I don't have a web server handy I'm writing them to disk.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create three MemoryStreams
MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") };
//I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk
byte[] bytes;
//Create our final combined MemoryStream
using (MemoryStream finalStream = new MemoryStream())
{
//Create our copy object
PdfCopyFields copy = new PdfCopyFields(finalStream);
//Loop through each MemoryStream
foreach (MemoryStream ms in streams)
{
//Reset the position back to zero
ms.Position = 0;
//Add it to the copy object
copy.AddDocument(new PdfReader(ms));
//Clean up
ms.Dispose();
}
//Close the copy object
copy.Close();
//Get the raw bytes to save to disk
bytes = finalStream.ToArray();
}
//Write out the file to the desktop
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.Write(bytes, 0, bytes.Length);
}
this.Close();
}
/// <summary>
/// Helper method to create temporary documents
/// </summary>
private MemoryStream CreateDoc(string name)
{
MemoryStream ms = new MemoryStream();
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
writer.CloseStream = false;
doc.Open();
doc.Add(new Paragraph(name));
doc.Close();
}
}
return ms;
}
}
}
While it seams the PdfReader can not take the stream, the array of the stream works.
var readerFrontPage = new PdfReader(streamFrontPage.ToArray());

Resources