Jump to content

iText geração formulários com iText


Nuno Miguel

Recommended Posts

Estou a criar um formulário dinâmico em pdf, através da api iText7.

O formulário consiste em vários campos que são dinâmicos e que por isso podem ser de vários tipos, string, inteiros, text, file, date etc.

Para isso, eu crio o pdfCrio os campos de acordo com os seus tipos e atribuo "tags" a esses campos.

Depois do lado do servidor, leio esse ficheiro, faço o corrimento desses campos/tags e com dados, associado a tags com o mesmo nome e que vêm de uma tabela da base de dados... faço o match com as respectivas tags do formulário.. preenchendo os seus valores.

Até aqui tudo bem.. percorria os 'fields' e fazia o setValue(...).. excepto quando era do tipo imagem.. pois se pusesse os bytes ele não funcionava.

Na documentação deles aqui deram-me esta solução:

CustomButton ad = new CustomButton((PdfButtonFormField) form.getField("advertisement"));
ad.setImage(ImageDataFactory.create(resource));
form.removeField("advertisement");
doc.add(new Paragraph().add(ad));

Basicamente pelo que percebi.. é uma martelada.. em vez de criar um campo do tipo imagem no pdf, crio um campo do tipo button e depois customizo-o com a imagem..

Funcionou muito bem durante vários meses até que alguém se lembrou de pôr não só uma imagem na primeira página do pdf (como era normal) mas tb na segunda.. e nestes casos a imagem que teoricamente deveria aparecer na segunda página aparecia no sitio respectivo.. mas na primeira. Já dei carradas de voltas pela net e pela documentação e não achei nada.

A olhar o código.. decidi dar um tiro no escuro pq não percebi bem o pq desta parte no código e comentei esta linha:

form.removeField("advertisement");

.. e por acaso a imagem já apareceu na segunda página.... mas continua tb aparecer na primeira.

Alguém tem alguma ideia do que poderá estar mal? Alguém já fez alguma coisa do género?

O método é este:

	private static byte[] fillform(DataFile dataFile, Long requestId) throws Exception
	{
		Request req = DeskmanFactory.getRequestRepository().findById(requestId);
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try
		{
			PdfDocument pdfDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(dataFile.getData())), new PdfWriter(baos));
			PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
			form.setGenerateAppearance(true);
			// PdfFont font = PdfFontFactory.createFont(FONT, PdfEncodings.IDENTITY_H);
			
			Document doc = new Document(pdfDoc);
			for(RequestTypeFields fld: req.getType().getFields())
			{
				//doc.flush();
				if(fld.getFieldTag() != null && fld.getFieldTag().trim().length() != 0)
				{
					if(form.getField(fld.getFieldTag()) != null && req.getField(fld.getFieldTag(), fld.getTitle()) != null) // se existir aquele field no form
					{
							List<RequestFile> rfList = DeskmanFactory.getRequestRepository().getRequestFileByRequest(req);
							if (rfList != null)
							{
								//TEMPORÁRIO 12/04/2019
								DataFile fieldDataFile;
								
								//sacar a imagem ou imagens que se tenha adicionado
								rfList = DeskmanFactory.getRequestRepository().getRequestFileByRequestAndFieldTag(req, fld.getFieldTag());
								
								if (req.getType().getType().equalsIgnoreCase("C")) //se for do tipo cartão vamos ler o extrafile
									fieldDataFile = rfList.get(0).getExtraDataFile();
								else
									fieldDataFile = rfList.get(0).getDataFile(); //se nao vamos ler o datafile original
								
								//convert byte[] to bufferedImage
								InputStream in = new ByteArrayInputStream(fieldDataFile.getData());							
								BufferedImage bimg = ImageIO.read(in);
								//merge
								BufferedImage overlay = MiraUtils.mergeImage(bimg);
								//convert bufferedImage to byte[]
								byte[] overlayInByte = MiraUtils.bytesFromBufferedImage(overlay, fieldDataFile.getExtension());
								//ImageData id = ImageDataFactory.create(fieldDataFile.getData());
								ImageData id = ImageDataFactory.create(overlayInByte);
								
								//sacar o 'botao' do pdf correspondente a um determinado field
								CustomButton ad = new CustomButton((PdfButtonFormField) form.getField(fld.getFieldTag()));
								
								//retirar o border
								//ad.setBorderColor(Color.WHITE);
								
								//settar a imagem no botão
								ad.setImage(id);
								
								//form.removeField(fld.getFieldTag()); //comentei.. para as imagens que não estão na primeira imagem poderem tb aparecer (embora tb continuem a aparecer na primeira)
								
								//criar o doc do pdf e acrescentar a costumização do botão
								doc.add(new Paragraph().add(ad));								
							}
					}
				}
			}

			KDate create = new KDate(req.getDateCreation());
			if(form.getField("dia") != null)
			{
				form.getField("dia").setValue("" + create.day());
				form.getField("dia").setBorderWidth(0f);
			}

			if(form.getField("mes") != null)
			{
				String mes = "";
				switch (create.month())
				{
					case (1):
						mes = "JAN";
						break;
					case (2):
						mes = "FEV";
						break;
					case (3):
						mes = "MAR";
						break;
					case (4):
						mes = "ABR";
						break;
					case (5):
						mes = "MAI";
						break;
					case (6):
						mes = "JUN";
						break;
					case (7):
						mes = "JUL";
						break;
					case (8):
						mes = "AGO";
						break;
					case (9):
						mes = "SET";
						break;
					case (10):
						mes = "OUT";
						break;
					case (11):
						mes = "NOV";
						break;
					case (12):
						mes = "DEZ";
						break;
					default:
						mes = "";
				}
				form.getField("mes").setValue(mes);
				form.getField("mes").setBorderWidth(0f);
			}

			if(form.getField("ano") != null)
			{
				form.getField("ano").setValue("" + create.year());
				form.getField("ano").setBorderWidth(0f);
			}

			if(form.getField("email") != null)
			{
				form.getField("email").setValue("" + req.getRequester().getEmail());
				form.getField("email").setBorderWidth(0f);
			}

			form.flattenFields();
			doc.close();
			pdfDoc.close();
		}
		catch(Exception e)
		{
			System.err.println("ERRO (RequestAction - fillform): "+e.getMessage());
			e.printStackTrace();
		}
		
		byte[] data = baos.toByteArray();
//		setFileInputStream(new ByteArrayInputStream(data));
//		setFname(df.getName());
//		setFmime(df.getMimeType());
		return data;
	}
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.