Unity 3d SharpPdf C# generation and display

6.2k views Asked by At

I was trying to figure out how to generate and display a pdf in a Unity app. I would like the app, and pdf to be available for iOS, Android and web app. Following this tutorial I was able to generate a pdf file and store in the app main folder within the simulator.

http://www.devindia.biz/unity-pdf-generation-with-sharppdf-plugin/

Unfortunately when I try to open the pdf inside the app using

Application.OpenURL("FILE://" + path);

It does not work.

I also tried iTextSharp with poor outcome and I believe it is not free anymore.

Any suggestion would be more than welcome.

Thanx

UPDATE

So I tried to move forward but I'm kind of stuck in the middle: I tried Gallorini's modified SharpPDF program, the generated pdf document, which I called "NewPDF.pdf" is stored in main application folder. Indeed when I run the code in the Editor I'm able to find it in there. I built a simple gui button and attached a void to it running this c# code to display the document as your suggestion:

public void openPdf(){
string path = Application.persistentDataPath + "/" + "newPDF.pdf";
Application.OpenURL(path);
Debug.log("Button Clicked");

}

when I click the button nothing happens except of course console records Button Clicked.

When I build the program for the web player the pdf is not generated although ApplicationOpenURL works and I am able to display a previously generated pdf by the editor.... I am a bit confused.

When I built the program for Mac Osx nothing happens at all.

On iPhone I get this log from Xcode console:

-> applicationDidBecomeActive()
Requesting Resolution: 1920x1080
Init: screen size 1920x1080
Initializing Metal device caps
Initialize engine version: 5.1.2f1 (afd2369b692a)

Adding Image Length 0 HEIGTH :8 WIDTH :8
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
sharpPDF.c__Iterator0:MoveNext()

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)

UnauthorizedAccessException: Access to the path "/newPDF.pdf" is denied.
at Mono.Security.Cryptography.RSAManaged.GenerateKeyPair () [0x00000] in :0
at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) [0x00000] in :0
at System.IO.FileStream..ctor (System.String path, FileMode mode) [0x00000] in :0
at sharpPDF.pdfDocument.createPDF (System.String outputFile) [0x00000] in :0
at SimplePDF+c__Iterator1.MoveNext () [0x00000] in :0

(Filename: currently not available on il2cpp Line: -1)

Adding Image Length 0 HEIGTH :8 WIDTH :8
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
sharpPDF.c__Iterator0:MoveNext()

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)

UnauthorizedAccessException: Access to the path "/newPDF.pdf" is denied.
at Mono.Security.Cryptography.RSAManaged.GenerateKeyPair () [0x00000] in :0
at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) [0x00000] in :0
at System.IO.FileStream..ctor (System.String path, FileMode mode) [0x00000] in :0
at sharpPDF.pdfDocument.createPDF (System.String outputFile) [0x00000] in :0
at SimplePDF+c__Iterator1.MoveNext () [0x00000] in :0

(Filename: currently not available on il2cpp Line: -1)

Button Clicked
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
SimplePDF:openPdf()
UnityEngine.Events.UnityAction:Invoke()
UnityEngine.Events.InvokableCall:Invoke(Object[])
UnityEngine.Events.InvokableCallList:Invoke(Object[])
UnityEngine.Events.UnityEventBase:Invoke(Object[])
UnityEngine.Events.UnityEvent:Invoke()
UnityEngine.UI.Button:Press()
UnityEngine.UI.Button:OnPointerClick(PointerEventData)
UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData)
UnityEngine.EventSystems.EventFunction`1:Invoke(ICancelHandler, BaseEventData)
UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
UnityEngine.EventSystems.TouchInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)
UnityEngine.EventSystems.TouchInputModule:ProcessTouchEvents()
UnityEngine.EventSystems.TouchInputModule:Process()
UnityEngine.EventSystems.EventSystem:Update()

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)

I am totally confused. Could you please help me out.

Thanx again.

UPDATE #2

I partially solved the problem:

I was able to generate the .pdf file in Unity Editor and in Standalone application on OSX. I realized I had trouble on storing/loading files in Unity.

// this is working on Editor. Application.dataPath are reached by the application and files are stored in Assets/StreamingAssets folder under project in Editor     

    #if UNITY_EDITOR || UNITY_EDITOR_64 
        myDoc.createPDF(Application.dataPath + "/StreamingAssets/" + attacName);


        myTable = null;

        #endif

// This is working on Mac standalone application. The file is correctly saved under Application.app/Contents folder

  #if UNITY_STANDALONE

    myDoc.createPDF(Application.dataPath + "/" + attacName);
    myTable = null;
        #endif

The code to retrieve and open the file:

public void openPdf() {
    string path;

        // tested working on mac

        #if UNITY_EDITOR || UNITY_EDITOR_64


        path = "file:" +Application.dataPath + "/StreamingAssets/" + attacName;


        #endif

        #if UNITY_STANDALONE

         path = "file:" +Application.dataPath + "/" + attacName;

        #endif

        Application.OpenURL(path);
        Debug.Log ("Button Clicked");

    }

So far everything works perfectly.

The pain comes with ios.

I was able to generate a pdf file with the above code in Application.persistentDataPath and getting it back from iTunes (to verify it was created) enabling UIFileSharingEnabled under info.plist. Here's the code:

   #if UNITY_IOS 
      myDoc.createPDF(Application.persistentDataPath + "/" + attacName);
      myTable = null;
    #endif

The trouble is when I try to Application.OpenUrl(path). It seems that c# code is blind to Application.persistentDataPath. Which by the way is /var/mobile/Containers/Data/Application/"ApplicationName"/Documents/"pdfName".pdf using

path = "file://" + Application.persistentDataPath + "/" + attacName;
    Application.OpenURL(path);

I tried also to save the file in StreamingAssets folder but Xcode didn't like it:

UnauthorizedAccessException: Access to the path "/private/var/mobile/Containers/Bundle/Application/F105683E-B2EA-4B0C-81B7-61302C58D56C/PdfReader.app/Data/newPDF.pdf" is denied. at Mono.Security.Cryptography.RSAManaged.GenerateKeyPair () [0x00000] in :0 at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) [0x00000] in :0 at System.IO.FileStream..ctor (System.String path, FileMode mode) [0x00000] in :0 at sharpPDF.pdfDocument.createPDF (System.String outputFile) [0x00000] in :0 at simplepdf+c__Iterator1.MoveNext () [0x00000] in :0

(Filename: currently not available on il2cpp Line: -1)

I then decided to get this wrapper

https://www.assetstore.unity3d.com/en/#!/content/17591

but it can only copy already formatted pdf file from StreamingAssets folder to /Raw folder on iOS device.

I am thinking I have to write my own wrapper to load data from Application.persistentDataPath on iOS, have you got any suggestion to start with?

Thank you again.

0

There are 0 answers