I am trying to generate PDF report with Jasper Reports using Spring. But report is always empty. I searched a lot and could not find problem. I tried to write byte[] pdfReport to OutputStream but result is same, report is always empty.
I have 2 parameters one o them is testName and one of them is chart. Both can not display at pdf report.
Thanks a lot for your help,
Here is the code that generates report.
//My class extends MultiActionController
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue(String.format("%s, %s", "pie1", "pie1"),20);
dataset.setValue(String.format("%s, %s", "pie2", "pie2"),80);
JFreeChart chart = ChartFactory.createPieChart("testPie", dataset, true, true, false);
Map model = new HashMap();
model.put("chart", chart.createBufferedImage(200, 200));
model.put("testName", "test report");
model.put("format", "pdf");
AbstractJasperReportsView view = new JasperReportsMultiFormatView();
view.setUrl("/WEB-INF/classes/reports/"+"test1"+".jasper");
view.setApplicationContext(getApplicationContext());
view.setContentType("application/pdf");
Properties header = new Properties();
view.setHeaders(header);
ModelAndView mv = new ModelAndView(view, model);
JasperReport report = (JasperReport) JRLoader.loadObject(getServletContext().getResourceAsStream("/WEB-INF/classes/reports/"+"test1"+".jasper"));
JasperPrint prt = JasperFillManager.fillReport(report, model);
byte[] pdfReport = JasperExportManager.exportReportToPdf(prt);
return mv;
And here is jrxml file
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="test1" language="groovy" pageWidth="700" pageHeight="842" columnWidth="660" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="2"/>
<parameter name="testName" class="java.lang.String"/>
<parameter name="chart" class="java.awt.Image" isForPrompting="false"/>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="48" splitType="Stretch"/>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="14" splitType="Stretch"/>
</columnHeader>
<detail>
<band height="229" splitType="Stretch">
<image>
<reportElement x="162" y="13" width="200" height="200"/>
<imageExpression class="java.awt.Image"><![CDATA[$P{chart}]]></imageExpression>
</image>
<textField>
<reportElement x="37" y="61" width="100" height="20"/>
<textElement/>
<textFieldExpression class="java.lang.String"><![CDATA[$P{testName}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band height="112" splitType="Stretch"/>
</columnFooter>
<pageFooter>
<band height="76" splitType="Stretch"/>
</pageFooter>
<summary>
<band height="42" splitType="Stretch"/>
</summary>
</jasperReport>
Why are you doing the following?
ModelAndView mv = new ModelAndView(view, model);
JasperReport report = (JasperReport) JRLoader.loadObject(getServletContext().getResourceAsStream("/WEB-INF/classes/reports/"+"test1"+".jasper"));
JasperPrint prt = JasperFillManager.fillReport(report, model);
byte[] pdfReport = JasperExportManager.exportReportToPdf(prt);
return mv;
Using JasperReportsMultiFormatView() already combines the filling and exporting of the report. No need for the following:
JasperReport report = (JasperReport) JRLoader.loadObject(getServletContext().getResourceAsStream("/WEB-INF/classes/reports/"+"test1"+".jasper"));
JasperPrint prt = JasperFillManager.fillReport(report, model);
byte[] pdfReport = JasperExportManager.exportReportToPdf(prt);
You must declare the JRXML file and report data key in a resource bundle.
I suggest you check this guide I wrote for Spring 3 MVC - Jasper Integration Tutorial:
http://krams915.blogspot.com/2010/12/spring-3-mvc-jasper-integration.html
Just modify the views to use the JasperReportsMultiFormatView() instead.
Check the Tutorials section for more. If I have time later, I'm gonna make a tutorial using JasperReportsMultiFormatView(). If not maybe tomorrow. Let me know if this helps you.
There is a property in jasper report called 'whenNoDataType'. Did you tried setting that to
whenNoDataType="AllSectionsNoDetail"
Also the report language is given as 'groovy'. Why?
Related
I have a PDF file I download from an API and save to internal storage using Environment.SpecialFolder.MyDocuments. When I attempt to open the file I get the error in the title, Failed to find configured root that contains /data/data/com.app.myapp/files/myfile.pdf.
Code that saves files:
var filePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName);
System.IO.File.WriteAllBytes(filePath, fileBytes);
LaunchIntent(filePath);
Code where error occurs:
public static void LaunchIntent(string fileLocation)
{
// now create an activity which points to the file
var localPath = global::Android.Net.Uri.Parse(fileLocation).Path;
File javaFile = new File(localPath);
//error occurs at below code
var filePath = global::Android.Support.V4.Content.FileProvider.GetUriForFile(
CrossCurrentActivity.Current.Activity,
CrossCurrentActivity.Current.Activity.PackageName + ".fileprovider",
javaFile);
var actionView = new Intent(Intent.ActionView);
actionView.AddFlags(ActivityFlags.GrantReadUriPermission);
var extension = localPath.Substring(localPath.LastIndexOf('.') + 1);
var mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
actionView.SetDataAndType(filePath, mimeType);
CrossCurrentActivity.Current.Activity.StartActivity(actionView);
}
My file paths file:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external" path="." />
<external-files-path name="external_files" path="." />
<cache-path name="cache" path="." />
<external-cache-path name="external_cache" path="."/>
</paths>
According to your description, you pdf is saved in internal storage, Provider path for a specific path as followings:
<files-path/> --> Context.getFilesDir()
<cache-path/> --> Context.getCacheDir()
<external-path/> --> Environment.getExternalStorageDirectory()
<external-files-path/> --> Context.getExternalFilesDir(String)
<external-cache-path/> --> Context.getExternalCacheDir()
<external-media-path/> --> Context.getExternalMediaDirs()
You can refer to: https://developer.android.com/reference/androidx/core/content/FileProvider
So change your resources/xml/file_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
<files-path name="internal_files" path="." />
</paths>
And adding a provider in the AndroidManifest.xml file Application tag.
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
I am getting the exception error: 'Unable to get provider androidx.core.content.FileProvider: java.lang.IllegalArgumentException: Missing android.support.FILE_PROVIDER_PATHS meta-data
Here is a bit of my code:
public void SendMMSMessage()
{
Android.Telephony.SmsManager smsMessage = Android.Telephony.SmsManager.Default;
IList<string> divideContents = smsMessage.DivideMessage("I auto sent this message to you! No typing here!!!!!");
string filePath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures) + "/TestPic.jpg";
byte[] sendPDUData = GetMMSPDUData("11111111111", filePath, "Hey this image was sent from my phone using code! No typing here");
if (sendPDUData != null)
{
SendMMSData(sendPDUData);
}
}
public byte[] GetMMSPDUData(string DestinationNumber, string AudioFilePath, string smsMessage)
{
byte[] pduData = null;
try
{
SendReq sendReq = new SendReq();
sendReq.AddTo(new EncodedStringValue(DestinationNumber));
PduBody pduBody = new PduBody();
// Add text message data to message
PduPart txtPart = new PduPart();
txtPart.SetData(Encoding.ASCII.GetBytes(smsMessage));
txtPart.SetContentType(new EncodedStringValue("text/plan").GetTextString());
txtPart.SetName(new EncodedStringValue("Message").GetTextString());
pduBody.AddPart(txtPart);
// Add image data
// TODO: Later, this will be audio file. But image file for testing
PduPart imgPart = new PduPart();
byte[] sampleImageData = System.IO.File.ReadAllBytes(AudioFilePath);
imgPart.SetData(sampleImageData);
imgPart.SetContentType(new EncodedStringValue("image/jpg").GetTextString());
imgPart.SetFilename(new EncodedStringValue(System.IO.Path.GetFileName(AudioFilePath)).GetTextString());
pduBody.AddPart(imgPart);
// Now create body of MMS
sendReq.Body = pduBody;
// Finally, generate the byte array to send to the MMS provider
PduComposer composer = new PduComposer(sendReq);
pduData = composer.Make();
}
catch(Exception ex)
{
// TODO: Do something here
}
return pduData;
}
public bool SendMMSData(byte[] PDUData)
{
Context CTX = Android.App.Application.Context;
Android.Telephony.SmsManager sm = Android.Telephony.SmsManager.Default;
Random rnd = new Random();
try
{
string cacheFilePath = System.IO.Path.Combine(CTX.CacheDir.AbsolutePath, "send." + "sendMe" + ".dat");
System.IO.File.WriteAllBytes(cacheFilePath, PDUData);
Java.IO.File testFile = new Java.IO.File(cacheFilePath);
string authString = CTX.PackageName + ".fileprovider";
if (System.IO.File.Exists(cacheFilePath))
{
Android.Net.Uri contentURI = AndroidX.Core.Content.FileProvider.GetUriForFile(CTX, CTX.PackageName + ".fileprovider", testFile);
// Android.Net.Uri contentURI = Android.Net.Uri.FromFile(testFile).Au
/* Android.Net.Uri contentURI = (new Android.Net.Uri.Builder())
.Authority(authString)
.Path(cacheFilePath)
.Scheme(ContentResolver.SchemeContent)
.Build();
*/
/*
* = (new Android.Net.Uri.Builder())
.Authority(ctx.PackageName + ".fileprovider")
.Path(cacheFilePath)
.Scheme(ContentResolver.SchemeContent)
.Build();
*/
PendingIntent pendingIntent = PendingIntent.GetBroadcast(CTX, 0, new Intent(CTX.PackageName + ".WAP_PUSH_DELIVER"), 0);
sm.SendMultimediaMessage(CTX, contentURI, null, null, null);
}
}
catch(Exception ex)
{
String exString = ex.ToString();
return false;
}
return true;
}
Also, here is my Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.janinesafety2" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
<application android:label="janinesafety2.Android">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.suport.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"
/>
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
</manifest>
and my Provider_path
<?xml version="1.0" encoding="utf-8" ?>
<paths>
<external-path
name="external_file"
path="./"
/>
</paths>
I have used these as resources to assist me in debugging:
androidx FILE_PROVIDER_PATHS
Unable to get provider androidx.core.content.FileProvider: java.lang.IllegalArgumentException: Missing android.support.FILE_PROVIDER_PATHS meta-data?
And unfortuntaly, I am still having issues with the expection. From what I can tell I am doing the exact thing everyone is saying.
Is there anyone there that can take a second a look at my code? Maybe I missed something.
Thank you.
You could refer to the code below.
1.Add the following to your AndroidManifest.xml inside the tags. YOUR_APP_PACKAGE_NAME must be set to your app package name.
<application>
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="YOUR_APP_PACKAGE_NAME.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
2.Add a new folder called xml into your Resources folder and add a new XML file called file_paths.xml. Add the following code:
<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
<external-path name="external" path="." />
<external-files-path name="external_files" path="." />
<cache-path name="cache" path="." />
<external-cache-path name="external_cache" path="." />
<files-path name="files" path="." />
</paths>
I added all the tags. You could get from the link below.
FileProvider - IllegalArgumentException: Failed to find configured root
I am using the NuGet.targets file from NuGet to automatically download NuGet.exe and then restore the packets in my project.
This was working well, however at work we have a proxy and this method was failing due to a (407) Proxy Authentication Required Exception. I modified the targets file to use the proxy details and although this method works in an application it does not work in the MSBuild Task, the code is identical.
If I hardcode the proxy and my login details it works, when I build my solution NuGet.exe is downloaded and the packages are restored correctly. The problem only appears to be the authentication in the MSBuild task, I have absolutely no idea why. I have attached my modified code.
If anyone can help I'd appreciate it. Thanks
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<OutputFilename ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Net" />
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="Microsoft.Build.Utilities" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try
{
OutputFilename = Path.GetFullPath(OutputFilename);
Log.LogMessage("Downloading latest version of NuGet.exe...");
using(WebClient webClient = new WebClient())
{
webClient.UseDefaultCredentials = true;
webClient.Proxy = WebRequest.GetSystemWebProxy();
webClient.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
return true;
}
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
After hours finally got why my app crashes after obfuscating by Obfuscar. That is StringHiding in MyClass. So settings for module now is
<SkipStringHiding type="Myspacename.MyClass" name="*" />
Now I need to hide only some of the strings inside MyClass. For example
private const string TrialLicenseKey = "AEAF3-N4C7K-BWDTV-3CLZB-XXXXX";
I was trying some combinatons of settings, but strings are still visible in Reflector.
Is ForceStringHiding supported? What is for name parameter? String content, var name, etc.?
<ForceStringHiding type="Myspacename.MyClass" name="???" />
Can't get why i see unobfuscated private static strings in Reflector
static Debugging()
{
A = new object();
__public = "AOMRDQELD+0rFgbQxySAHrBpU3N8RF1i3rXkgSC79aXEgE=";
D = "ActivationHardwareId";
d = "LicenseKey";
E = "ActivationKey";
...
}
settings for Obfuscar
<Var name="KeepPublicApi" value="true" />
<Var name="HidePrivateApi" value="true" />
<Var namr="HideStrings" value="true" />
I am trying to transform an xml from one format to another using smooks. The source xml looks like what is shown below:
<page>
<responsedata>
<header>
...
<ref_no>xyz</ref_no>
</header>
<detail>
<acc_no>x</acc_no>
<ac_ccy>y</ac_ccy>
<avail_bal>z</avail_bal>
</detail>
<detail>
...
</detail>
</responsedata>
</page>
I am trying to tranform the above to something like this:
<detail>
<ref_no>xyz</ref_no>
<accounts>
<account>
<Account_no>x</Account_no>
<Curr>y</Curr>
<Avail_Bal>z</Avail_Bal>
</account>
<account>
...
</account>
</accounts>
</detail>
For this, I used the following smooks configuration:
<ftl:freemarker applyOnElement="responsedata">
<ftl:template><!--<?xml version="1.0" encoding="UTF-8" ?>
<DETAIL>
<Ref_No>????<Ref_No> //how to bring the ref_no here
<Accounts>
<?TEMPLATE-SPLIT-PI?>
</Accounts>
</DETAIL>
--></ftl:template>
</ftl:freemarker>
<ftl:freemarker applyOnElement="detail">
<ftl:template><!--
<Account>
<Account_no>${detail.acc_no}</Account_no>
<Curr>${detail.ac_ccy}</Curr>
<Avail_Bal>${detail.avail_bal}</Avail_Bal>
</Account>
--></ftl:template>
</ftl:freemarker>
Except for the reference number, I am able to transform everything else. Any suggestions on how to accomplish this would be highly appreciated.
Could you use the Smooks javabean capability to bind that value to a Java object (just put in a HashMap) and then access that bean from the Freemarker template?
<resource-config selector="header">
<resource>org.milyn.javabean.BeanPopulator</resource>
<param name="beanId">header</param>
<param name="beanClass">java.util.HashMap</param>
<param name="bindings">
<binding property="refNo" selector="header/ref_no" />
</param>
</resource-config>
<resource-config selector="header">
<resource type="ftl">
<![CDATA[<detail>
<ref-no>${header.refNo}</ref-no>
...
</detail>]]>
</resource>
</resource-config>