Open a file from crystal report export to stream function - crystal-reports

How can i open a file directly from stream which is exported through crystal report export to stream function? I am using vs2010 and sap crystal report.
MemoryStream m = (MemoryStream)(PReport.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat));
FileStream f = new FileStream(purchaseCombo.SelectedItem.ToString(),FileMode.Create,System.IO.FileAccess.Write);
byte[] bytes = new byte[m.Length];
m.Read(bytes, 0, (int)m.Length);
f.Write(bytes, 0, bytes.Length);
f.Close();
m.Close();

It depends on the file that you are exporting. Since Crystal Reports can export a number of different file types and each of them has a specific program that can handle it, you will need to search for the exact file type that you're interested. For example with a quick search on the internet, I found that a stream of an html file can be directly previewed inside a WebBrowser component (in a WPF app) by using the NavigateToStream method. Maybe there are some 3rd party components that expose methods for directly opening files from memory.
Though, the easiest way would be to export a temporary file to disk instead of memory by using the ExportToDisk method and delete it after its usage, since many components read from paths rather than memory. Before exporting the file, you can use the GetTempFileName method which creates and names a temporary file.

Related

Can OpenXML be used to launch a new Word instance?

I'm able to generate Word documents without issue. I save the resulting *.docx file to a temporary location and then need to launch the file in Word.
The requirement is to not "open" the file in Word (easily done with a Process.Start) but to have load into Word as a new unsaved file. This is because certain propriety integrations for Word need to take over when a user saves the file and don't kick in if the file is ready saved but to a location on disk.
I've achieved this by using Interop calls to the Word application, adding the new document to Word's workspace. My problem is with Interop which tends to break on various client machines, particularly when Office upgrades take place (say a client had 32-bit office but upgraded with a 64-bit version).
I'm somewhat new to OpenXML, but can it be used to automate Word or is Interop my only real option?
object oFilename = tmpFileName;
object oNewTemplate = false;
object oDocumentType = 0;
object oVisible = true;
Document document = _application.Documents.Add(ref oFilename, ref oNewTemplate, ref oDocumentType, ref oVisible);
No, the Open XML technology has no way of interacting with the Office (Word) application - it's for file creation/manipulation, only. The interop is required in order to do anything with the Word application.
There is sort of a way around this - and it's only possible with Word, no other Office application has this - is to convert the Open XML content to the OPC flat-file format. This "concatenates" the various packages that make up the zip file to a pure text string, essetially a single XML file.
XML content in the OPC flat-file format can then be written to an already opened (even newly created) Word document using the Range.InsertXML method via "the interop". In a way, this "streams" the Open XML content into the opened Word document.
The problem with this approach is that certain document-level properties are not written to the target document, so not all aspects of the opened document can be changed. For example: page size, orientation, headers, footers... So if this kind of thing also needs to be affected the interop is required for such settings.

How to make a section optional when mapped to optional data in a Word OpenXml Part?

I'm using OpenXml SDK to generate word 2013 files. I'm running on a server (part of a server solution), so automation is not an option.
Basically I have an xml file that is output from a backend system. Here's a very simplified example:
<my:Data
xmlns:my="https://schemas.mycorp.com">
<my:Customer>
<my:Details>
<my:Name>Customer Template</my:Name>
</my:Details>
<my:Orders>
<my:Count>2</my:Count>
<my:OrderList>
<my:Order>
<my:Id>1</my:Id>
<my:Date>19/04/2017 10:16:04</my:Date>
</my:Order>
<my:Order>
<my:Id>2</my:Id>
<my:Date>20/04/2017 10:16:04</my:Date>
</my:Order>
</my:OrderList>
</my:Orders>
</my:Customer>
</my:Data>
Then I use Word's Xml Mapping pane to map this data to content control:
I simply duplicate the word file, and write new Xml data when generating new files.
This is working as expected. When I update the xml part, it reflects the data from my backend.
Thought, there's a case that does not works. If a customer has no order, the template content is kept in the document. The xml data is :
<my:Data
xmlns:my="https://schemas.mycorp.com">
<my:Customer>
<my:Details>
<my:Name>Some customer</my:Name>
</my:Details>
<my:Orders>
<my:Count>0</my:Count>
<my:OrderList>
</my:OrderList>
</my:Orders>
</my:Customer>
</my:Data>
(see the empty order list).
In Word, the xml pane reflects the correct data (meaning no Order node):
But as you can see, the template content is still here.
Basically, I'd like to hide the order list when there's no order (or at least an empty table).
How can I do that?
PS: If it can help, I uploaded the word and xml files, and a small PowerShell script that injects the data : repro.zip
Thanks for sharing your files so we can better help you.
I had a difficult time trying to solve your problem with your existing Word Content Controls, XML files and the PowerShell script that added the XML to the Word document. I found what seemed to be Microsoft's VSTO example solution to your problem, but I couldn't get this to work cleanly.
I was however able to write a simple C# console application that generates a Word file based on your XML data. The OpenXML code to generate the Word file was generated code from the Open XML Productivity Tool. I then added some logic to read your XML file and generate the second table rows dynamically depending on how many orders there are in the data. I have uploaded the code for you to use if you are interested in this solution. Note: The xml data file should be in c:\temp and the generated word files will be in c:\temp also.
Another added bonus to this solution is if you were to add all of the customer data into one XML file, the application will create separate word files in your temp directory like so:
customer_<name1>.docx
customer_<name2>.docx
customer_<name3>.docx
etc.
Here is the document generated from the first xml file
Here is the document generated from the second xml file with the empty row
Hope this helps.

Combine two TCPDF documents

I'm using TCPDF to create two separate reports in different parts of my website. I would like that, in the end of the first report, the second report should be loaded.
It's different than import a PDF file, because the second report is also generated by TCPDF. Is there a way to do this?
I assume from your question that what you ultimately want to provide is one PDF file that consists of the first PDF concatenated with the second PDF.
One quick and dirty solution is to utilize the pdftk command line PDF processor and call it from within your PHP code using the exec() function. The pdftk command has many features and concatenating files is only one of them, but it does an awesome job. Depending on your hosting situation, this may or may not be an option for you.
The other option would be to use FPDI to import the two PDF files and concatenate them within your PHP code and then send the concatenated version to the user.
More information on using PFDI here:
Merge existing PDF with dynamically generated PDF using TCPDF
Given that you're already using TCPDF, importing the pre-existing file that you want to concatenate with the one you've just created shouldn't be too difficult.
Just add FPDI to your project/composer from:
https://www.setasign.com/products/fpdi/downloads/
Can you still used tcpdf.
FPDI support all the methods of tcpdf, just used new FPDI() instead new tcpdf() the result will be the same in your report, after you create your report marge the files with the code from this page:
https://www.setasign.com/products/fpdi/about/
In a loop, once set the first file and after this set the second...
If you will need help i am here for you.

ObjectScript file create from stream

how can I create file (PDF file for example) from binary stream I have stored in global? I have stream stored in caché global and I need to create and save the file created by the stream using ObjectScript.
Thanks :)
It is not so easy. There is only one official way to create pdf in Cache, and it is ZEN reports. With ZEN reports you could create not only pdf, also possible to make html, xlsx. ZEN Reports used Apache FOP for generating it, any other ways also possible, but you should do it only by yourself.
Or maybe I misunderstood you, and you mean that your binary stream already contains PDF, and you just want to save it to some file. If so, you just have to copy your globalstream to filestream, with code like this:
set fs=##class(%Stream.FileBinary).%New()
set fs.Filename="c:\temp.pdf"
set tSC=fs.CopyFrom(yourStream)
set tSC=fs.%Save()

CrystalReportSource binding

Hello I have a crystalReportViewer and CrystalReportSource on a web form.
I need to be able to bind the reportSource at run time to different report files.
I have the file data stored in a blob in a DB.
The mechanism I am using now is to save the blob to a file and then
this.CrystalReportSource1.Report.FileName = myFileName;
The issue is that I want to avoid saving the file on disk and somehow bind the report directly to a file stream.
Is that possible?
Thanks
In C#, I believe that you should be able to use something like the following, but I haven't tested it out on my system.
ReportDocument rpt = new ReportDocument();
rpt.Load(filestream); //filestream is your filestream object
Give it a try and let me know if you have issues.