# Sending MemoryStream

## How it Works

### [Run sample](http://oz.ozeform.io/oz/edu/clientbind/export.html)

1. The sample opens an empty viewer first.
2. Select and open an OZR from the select option **`repository_files/demo`**.
3. Enter your input data in the form.
4. Click the Export button. The current open form will be exported to the server in the specified format.
5. The exported target file will be listed in the pane **`webapps/EXPORT`.**
6. You can open exported files again.

### Features

#### Client

1. Open an empty viewer
2. Open OZR/OZD in the empty viewer
3. Export OZR/OZD to OZD/PDF and send OZD/PDF to the server

#### Server

1. Receive OZD/PDF from the client and save it as OZD/PDF

## Implementation

### License

The **OZ Server Binding** license is required in the OZ Server license file as below.

<mark style="color:blue;">`USE-SERVERBIND="TRUE"`</mark>

### Open Empty Viewer

* Set the viewer parameter **viewer.emptyframe** to **true**.

{% tabs %}
{% tab title="export.html" %}

```javascript
<!DOCTYPE html>
<html style="height:100%">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<!-- HTML5 Viewer references-->
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" type="text/css"/>
<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="/html5viewer/ui.dynatree.css" type="text/css"/>
<script type="text/javascript" src="/html5viewer/jquery.dynatree.js" charset="utf-8"></script>
<script type="text/javascript" src="/html5viewer/OZJSViewer.js" charset="utf-8"></script>
</head>
<body style="width:98%;height:98%">
<div id="OZViewer" style="width:98%;height:98%"></div>

<script type="text/javascript" >

function SetOZParamters_OZViewer()    {    
    var oz = document.getElementById("OZViewer");
    oz.sendToActionScript("viewer.emptyframe", "true");    
    return true;
}
start_ozjs("OZViewer", "/html5viewer/");

</script>
</body>
</html>
```

{% endtab %}
{% endtabs %}

### Open OZR

```html
<!-- Add a button to open OZR-->
<input type="button" value="OpenOZR" onclick="openForm('ozr')" >
```

```javascript
// Add a function to open OZR by the button OpenOZR
function openForm(type){    
    if (type == "ozr") {
        var url = "forcs/john.kim/customer.ozr";
        var param = "connection.reportname=" + url + "; ";
    } 
    param += "connection.servlet=/training/server; ";
    param += "viewer.pagedisplay=singlepagecontinuous; ";
    param += "viewer.viewmode=fittoframe; ";
    param += "eform.signpad_type=dialog; ";
    param += "comment.all=true; ";
    param += "comment.selectedpen=highlightpen; ";
    OZViewer.CreateReportEx(param, ";");
}
```

### Open OZD

1. Create a folder named ***EXPORT*** under the ***webapps*** folder.
2. Get OZD from the viewer.
3. Save it to the ***EXPORT*** and ***repository\_files.***

```html
<!-- Add a button to open OZD -->
<input type="button" value="OpenOZD" onclick="openForm('ozd')" >
```

```javascript
// Add lines to open OZD
function openForm(type){    
    if (type == "ozr") {
        var url = "forcs/john.kim/customer.ozr";
        var param = "connection.reportname=" + url + "; ";
    } else if (type == "ozd") {
        //var url = "ozp://forcs/john.kim/customer.ozd"; 
        var url = "http://localhost:8080/EXPORT/customer.ozd";       
        var param = "connection.openfile=" + url + "; ";
    }
```

### Close Viewer

```html
<!-- Add a button to close OZR/OZD -->
<input type="button" value="Close" onclick="closeForm()" >
```

```javascript
// Add a function to close OZR/OZDS
function closeForm() {
    OZViewer.Script("close"); // The last viewer will be closed first
    //OZViewer.Script("closeall"); // Remove all open viewer
}
```

### Client-Side Exporting with MemoryStream

<table><thead><tr><th width="150">Side</th><th width="584.8832487309644">Action</th></tr></thead><tbody><tr><td>Client</td><td><ol><li><strong>ScriptEx("save_memorystream")</strong> converts the form as a memory stream in the specified format (OZD or PDF) and raises the event OZExportMemoryStreamCallBack. </li><li><strong>ExportMemoryStreamCallBack_OZViewer</strong>(outputdata) triggered by OZExportMemoryStreamCallBack event receives the memory stream encoded in base64 with <strong>outputdata</strong> argument.</li><li>Sends the memory stream to the server application in the function <strong>OZExportMemoryStreamCallBack_OZViewer</strong></li></ol></td></tr><tr><td>Server</td><td><ol><li>Receives the memory stream, decodes it, and saves it as a file in the target format.</li><li>Sends the target file path to the client.</li></ol></td></tr><tr><td>Client</td><td><ol><li><strong>streamCallback</strong> receives the target file path.</li></ol></td></tr></tbody></table>

{% tabs %}
{% tab title="export.html" %}

```javascript
<!-- Add a button and form -->
<input type="button" value="ExportStream" onclick="exportStream()" >
<form id="form">	
    <input type="hidden" id="fileName" name="fileName">
    <input type="hidden" id="targetFormat" name="targetFormat">
    <input type="hidden" id="stream"	name="stream">
</form>

// Add JavaScript
var fileName = "customer.ozr"; // or ozd
var targetFormat = "ozd"; // or pdf

function exportStream() {
    var param = "export.format=" + targetFormat;
    param += "; export.path=C:\\TEMP;"
    param += "; export.filename=temp"; 
    param += "; export.mode=silent";
    param += "; export.confirmsave=false";
    param += "; ozd.allowreplaceformparam=true";
    param += "; pdf.savecomment=true";
    OZViewer.ScriptEx("save_memorystream", param,";");                     
}

function OZExportMemoryStreamCallBack_OZViewer(outputdata) {
    if(outputdata == "{}") {
      alert("Export failed.");
    }else {
        var obj = eval('(' + outputdata + ')');
        var value = null;
        for(var key in obj) value = obj[key];

        $('#fileName').val(fileName);
        $('#targetFormat').val(targetFormat);
        $('#stream').val(value);
        var param = $('form').serialize();    

        $.ajax({
            type : "POST",
            url : "./save-stream.jsp",
            data : param,
            async : false,
            success : streamCallback,
            error : function(request, status, error) {
                if (request.status != '0') {
                    alert("code : " + request.status + "\r\nmessage : "    + request.reponseText + "\r\nerror : " + error);
                }
            }
        });
    }       
}
var streamCallback = function(path){
    alert(path);
};
```

{% endtab %}

{% tab title="save-stream.jsp" %}

```java
<%@ page language="java" import="java.io.*,sun.misc.*,org.xml.sax.InputSource,org.w3c.dom.*, javax.xml.parsers.*, java.util.*, java.text.*" contentType="text/html; charset=UTF-8" autoFlush="true"%><%!
    public String encoder(String key) {
        return new BASE64Encoder().encode(key.getBytes());
    }
    public byte[] decoder(String cipher) throws IOException {
        return new BASE64Decoder().decodeBuffer(cipher);
    } 
%><%
try {
    request.setCharacterEncoding("utf-8");
    String path = "C:/Program Files/Apache Software Foundation/Tomcat 9.0/webapps/EXPORT/"; 
    String fileName = request.getParameter("fileName");
    String targetFormat = request.getParameter("targetFormat");
    String base64Str =  request.getParameter("stream");

    String file = fileName.substring(0, fileName.length()-4);
    int i = file.indexOf('-');
    if (i > 0) {
        file = file.substring(0, i);
    }

    String targetFile = file + "-" + timeStamp + "." + targetFormat;
    String targetPath = path + targetFile;

    byte[] decodedBytes = new BASE64Decoder().decodeBuffer(base64Str.substring(base64Str.indexOf(",")+1));
    try {    
        FileOutputStream fout = new FileOutputStream(targetPath);
        fout.write(decodedBytes, 0, decodedBytes.length);
        fout.close();
        out.println(targetPath);
    } catch (IOException e) {
        e.printStackTrace();
    } 
}
catch(Exception e) {
    out.print(e.getMessage());
} finally {
}
%>
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="313.70942431622234">Option</th><th width="371.9568818620002">Description</th></tr></thead><tbody><tr><td>export.path=C:\TEMP</td><td>path for the <strong>save</strong> option</td></tr><tr><td>export.filename=temp</td><td>file name for the <strong>save</strong> option</td></tr><tr><td>export.mode=silent</td><td>no <strong>Save</strong> diaog box</td></tr><tr><td>export.confirmsave=false</td><td>no <strong>Save as</strong> window</td></tr><tr><td>pdf.savecomment=true</td><td>export to pdf with comments</td></tr><tr><td>ozd.allowreplaceformparam=true</td><td>allow created OZD to receive parameter values</td></tr><tr><td>save_memorystream</td><td>save as a memory stream</td></tr><tr><td>save</td><td>save as a file on the client</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://edu.ozeform.io/e-form-developer/day-3/implementation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
