I’ve been struggling for days and I still can’t figure it out. So here we go:
I want to create PDFs in runtime on Android and iOS. So I’ve tried many solutions (PDFSharp, iTextSharp, iText 7, etc…), some compile and produces bugs and some don’t even compile.
Now i’m testing iText 7 and I’m stuck at this point: it’s compiling, the application is running, I can create an empty PDF and save it, BUT: when I add text in it, it doesn’t want to save it anymore and I’m getting this error in Logcat (when compiled in Mono):
2022/09/22 11:14:51.597 3866 3906 Error Unity ArgumentException: The specified path is not of a legal form (empty).
2022/09/22 11:14:51.597 3866 3906 Error Unity at System.IO.Path.InsecureGetFullPath (System.String path) [0x00025] in <c00f838d158c4f4185913cb3b6f74bb2>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at System.IO.Path.GetFullPath (System.String path) [0x00000] in <c00f838d158c4f4185913cb3b6f74bb2>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at System.AppDomainSetup.GetAppBase (System.String appBase) [0x00038] in <c00f838d158c4f4185913cb3b6f74bb2>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at System.AppDomainSetup.get_ApplicationBase () [0x00000] in <c00f838d158c4f4185913cb3b6f74bb2>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at System.AppDomain.get_BaseDirectory () [0x00006] in <c00f838d158c4f4185913cb3b6f74bb2>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at (wrapper remoting-invoke-with-check) System.AppDomain.get_BaseDirectory()
2022/09/22 11:14:51.597 3866 3906 Error Unity at iText.Commons.Utils.FileUtil.GetBaseDirectory () [0x00005] in <70ff0a0b3dd34b239fd922ab105d65e4>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at iText.IO.Util.ResourceUtil.LoadITextResourceAssemblies () [0x0007e] in <c831a68b61cf41899c27077df1818d79>:0
2022/09/22 11:14:51.597 3866 3906 Error Unity at iText.IO.Util.ResourceUtil..cctor () [0x00034] in <c831a68b61cf41899c27077df1818d79>:0
And I’m getting this error in Logcat (when compiled in IL2CPP):
2022/09/22 11:30:22.047 5138 5190 Error Unity IOException: Permission denied
2022/09/22 11:30:22.047 5138 5190 Error Unity Rethrow as UnauthorizedAccessException: Access to the path '/' is denied.
2022/09/22 11:30:22.047 5138 5190 Error Unity at System.IO.Enumeration.FileSystemEnumerator`1[TResult].CreateDirectoryHandle (System.String path, System.Boolean ignoreNotFound) [0x00000] in <00000000000000000000000000000000>:0
2022/09/22 11:30:22.047 5138 5190 Error Unity at System.IO.Enumeration.FileSystemEnumerator`1[TResult]..ctor (System.String directory, System.IO.EnumerationOptions options) [0x00000] in <00000000000000000000000000000000>:0
2022/09/22 11:30:22.047 5138 5190 Error Unity at System.IO.Enumeration.FileSystemEnumerable`1+DelegateEnumerator[TResult]..ctor (System.IO.Enumeration.FileSystemEnumerable`1[TResult] enumerable) [0x00000] in <00000000000000000000000000000000>:0
2022/09/22 11:30:22.047 5138 5190 Error Unity at System.IO.Enumeration.FileSystemEnumerable`1[TResult]..ctor (System.String directory, System.IO.Enumeration.FileSystemEnumerable`1+FindTransform[TResult] transform, System.IO.EnumerationOptions options) [0x00000] in <00000000000000000000000000000000>:0
2022/09/22 11:30:22.047 5138 5190 Error Unity at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles (System.String directory, Sy
And here is my code:
using UnityEngine;
using iText.Kernel.Pdf;
using iText.Kernel.Geom;
using iText.Layout.Element;
using iText.Layout;
using System.IO;
using iText.IO.Image;
using UnityEngine.Android;
public class ExportPDF : MonoBehaviour
{
[SerializeField]
private Texture2D img;
private string content;
private NativeShare nativeShare;
private string pdfpath;
// Start is called before the first frame update
void Start()
{
if (Application.platform == RuntimePlatform.Android)
{
if (!Permission.HasUserAuthorizedPermission(Permission.CoarseLocation))
Permission.RequestUserPermission(Permission.CoarseLocation);
if (!Permission.HasUserAuthorizedPermission(Permission.FineLocation))
Permission.RequestUserPermission(Permission.FineLocation);
if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead))
Permission.RequestUserPermission(Permission.ExternalStorageRead);
if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
Permission.RequestUserPermission(Permission.ExternalStorageWrite);
string path = Application.persistentDataPath + System.IO.Path.DirectorySeparatorChar + "pdffolder";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
pdfpath = path + System.IO.Path.DirectorySeparatorChar + "test.pdf";
}
else
{
pdfpath = Application.persistentDataPath + "/test.pdf";
}
nativeShare = new NativeShare();
nativeShare.SetSubject("Test");
nativeShare.SetText("TEST");
nativeShare.SetTitle("Share test");
}
public void Export()
{
PdfWriter wri = new PdfWriter(pdfpath);
PdfDocument pdf = new PdfDocument(wri);
pdf.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
pdf.GetCatalog().SetLang(new PdfString("en-US"));
PdfDocumentInfo info = pdf.GetDocumentInfo();
info.SetTitle("TEST");
pdf.AddNewPage();
Document document = new Document(pdf, PageSize.A4);
document.Add(new Image(ImageDataFactory.Create(img.EncodeToPNG())));
Paragraph header = new Paragraph(new Text("Hello World!").SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).SetFontSize(20));
document.Add(header);
document.Close();
nativeShare.AddFile(pdfpath);
nativeShare.Share();
}
}
My settings:
IL2CPP
.NET Framework
ARM64
Strip Engine Code: UNCHECKED
Managed Stripping Level: Minimal
Now multiple questions:
Has anyone ran into this issue before? If yes, did you find a solution? If yes, could you help me?
If I’m going in the wrong direction, could someone show me which PDF library is working in Unity (runtime) please?
If someone could help me that would be amazing! Thanks for reading me!
Thanks for the answer, yes I’ve tried and it does the same error. But the wierdest thing about this, is that if I remove line 63 which is document.Add(header); (adding text to the pdf file) then it saves the file and it works without any error! So I can save a PDF but it has to be without text lol (which is useless)…
Hello! I’ve found a free solution that works on both iOS and Android in runtime. It works with iTextSharp but you need to take the version 5 and not the 7 as the 5 is free and the 7 is under commercial license. So what you need to do is :
Extract it and copy the files that are under the “lib” folder to the “Plugins” folder of your unity project
Go back on the link of the first step and go to the “Dependencies” tab and download the needed dependencies, follow the same process and add the *.dll and *.xml files to the “Plugins” folder of your unity project
Unity is gonna give you a bunch of missing dependencies errors but don’t worry: for every missing dependency, go to nuget.org, look for the missing dependency, download it, and follow the same process as previously
As you fill all the required dependencies, it will display no error at a certain point
At this moment it’s done, you can begin scripting with the iTextSharp library
I know the process is laborious but I assure you it works as I’m still working with it, if you need help, feel free to send me a private message!
I found iTextSharp on NuGet and added it to the project.
All dependencies were automatically pulled into the My App/Packages/ folder.
I copied all new folders from My App/Packages/ to My App/Asset/Plugins/.
I unsubscribed and removed all the new ones from NuGet.
I encountered another problem. iTextSharp loses encodings for custom fonts, but only after the build. I needed to be able to write in different languages in the PDF file - international fonts. I added my own font and everything worked fine in runtime. But after the build, I got an error saying “1252 encoding not found”.
From various sources, I learned that I needed to add the i18n.dll and i18n.west.dll assemblies to the My App/Asset/Plugins/ folder. Apparently, iTextSharp relies on them, but Unity doesn’t include them in the final build. But that’s only half the battle. The i18n.dll and i18n.west.dll files are located in Unity directories. However, in newer versions of Unity, these dll files may not be suitable (or I didn’t search well enough). Eventually, I accidentally found the suitable libraries on a 2017 GitHub repository. I downloaded them from there and added them to my project.
In general, this is very useful information for iTextSharp users on Unity. You may want to add support for different languages or change the font style in your project =)
I will attach the link below. I hope this post will help many people. I suffered for a long time myself)
Yes for the i18n.dll and i18n.west.dll, I also wanted to change the font and ran into the same issue and resolved it the same way you did, I didn’t mention it but I’m glad you did!