Originalmente, queríamos generar documentos en el lado de Android (esto requiere ...). Al final, no hay un buen método que pueda ser perfecto para Android, y al final, solo podemos pasar al servidor. No lo desperdicie, pero registre las razones por las cuales cada marco no admite Android y sus características. Todavía hay muchos de estos marcos relacionados con Java, y algunos no son malos, pero desafortunadamente no admiten Android, o cobran por una tarifa y tienen un precio bajo.
Después de las pruebas personales, muchos paquetes AWT que no admiten Java no pueden usarse directamente en Android. Freemarker es bastante bueno y puede generar documentos complejos y hermosos, pero desafortunadamente no es compatible con Android. Puede ejecutarse en Android usando POI, pero ha pasado por muchas dificultades en el camino debido a la versión, el formato, etc., y todavía está confuso para abrir con WFS. JWord y Aspose.Word pueden ser perfectamente compatibles, y el período de libertad condicional JWORD es de solo 30 días, ambos se cobran por ambos. Itext no tiene prueba, pero se dice que no admite Android.
Método 1: Freemarker
Este método requiere crear manualmente una plantilla de documento (recuerde usar marcadores de posición para la imagen) y guardarla como un archivo XML. Genere reemplazando dinámicamente el contenido en la etiqueta específica $ {}. ejemplo:
Primero, tomemos las representaciones:
public class docutil {Configuración pública Configuración = NULL; public DocUtil () {configure = nueva configuración (configuración.version_2_3_22); configure.setDefaultEncoding ("UTF-8"); } /*** Genere el archivo de palabras basado en la plantilla de doc* @param dataMap Los datos que deben completarse en la plantilla* @param descargar el nombre del archivo* @param savePath guardar ruta* /public void CreatedOC (map <string, objeto> dataMap, string downlowType save savePath) {intent {// cargar la plantilla que debe ser cargada de temperatura; // Establecer el método y la ruta del dispositivo de plantilla, Freemarker admite múltiples métodos de carga de plantillas. Puede recargar el servicio de servlet, classpath y de la base de datos. // Cargue el archivo de plantilla y colóquelo en TestDoc configure.setClassfortEmplateloading (this.getClass (), "/testDoc"); // Establecer el contenedor de objetos // configure.setObjectWrapper (new DefaultObjectWrapper ()); // Establezca el controlador de excepciones Configure.settemplateExceptionHandler (TemplateExceptionHandler.ignore_handler); // Definir el objeto de plantilla, tenga en cuenta que el nombre del tipo de plantilla debe ser consistente con la plantilla downloadType = configure.gettemplate (downloadType+". Xml"); Archivo outFile = nuevo archivo (savePath); Escritor fuera = nulo; out = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (OUTFILE), "UTF-8")); Template.process (datamap, out); out.close (); } catch (ioException e) {E.PrintStackTrace (); } catch (TemplateException e) {E.PrintStackTrace (); }} public String getImagestr (string imgfile) {inputStream in = null; byte [] data = null; intente {in = new FileInputStream (imgFile); data = new Byte [in.available ()]; in.read (datos); cercar(); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } Base64Encoder Encoder = new Base64Encoder (); return encoder.encode (datos); }} public class testDoc {public static void main (string [] args) {docutil docutil = new docutil (); Map <string, object> datAMAP = new HashMap <String, Object> (); datAMAP.put ("Nombre", "Joanna"); datAMAP.put ("Examnum", "11111111111111"); datamap.put ("idcard", "222222222222222222222222222222222222222222222222222222222222222222222222222222222222 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222; datamap.put ("Carmodel", "C1"); docutil.getImagestr ("d: //img//userimg1.png")); datAMAP.put ("FirstExCores", "0 puntos, fallido"); datAMAP.put ("FirstPic2", docutil.getImagestr ("d: //img//firstpic2.png"); "12: 46: 50-13: 05: 37"); datAMAP.put ("SecondExamScores", "90 puntos, pase"); datAMAP.put ("SECCEDEDUCTITEM", ""); datAMAP.put ("Secondpic1", docutil.getImagestr ("d: //img//secondpic1.png")); datAMAP.put ("Secondpic2", docutil.getImagestr ("d: //img//secondpic2.png")); datAMAP.put ("Secondpic3", docutil.getimagestr ("d: //img//secondpic3.png")); docutil.createDoc (datAMAP, "baseC", "d: //yanqiong.doc"); }} El archivo XML es demasiado largo, así que no lo publicaré ...
Finalmente, la razón por la que no se puede usar Android: http://stackoverflow.com/questions/25929542/use-freemarker-library-in-android
Preguntas adicionales sobre la visualización dinámica de listas y saltos de línea
El requisito es claro: en el elemento de deducción anterior, si tengo varios elementos de deducción, quiero que se muestre cada ruptura de línea.
Agregar nuevas líneas directamente al contenido que se mostrará no tiene efecto y no funcionará como una nueva línea.
Al agregar etiquetas FTL, como <#list> </list>, surgirán algunos problemas, que no se reconocen en el XML, lo que resulta en que el proyecto no pueda ejecutarse.
resolver:
Agregue y agregue descansos de línea a la posición donde se deben mostrar múltiples elementos de deducción:
<#list FirstDeducTitem como FirstItem>
<w: t> $ {FirstItem} </w: t> <w: br/>
</#list>
Cambiarlo a:
Lista <String> strs = new ArrayList <String> ();
Strs.add ("11111111111111111111");
Strs.add ("2222222222222222222222222222);
Strs.add ("33333333333333");
datAMAP.put ("FirstDeducTiTem", Strs);
Cambiarlo a docutil.java:
// Defina el objeto de plantilla, tenga en cuenta que el nombre del tipo de plantilla debe ser consistente con DownloodPe
Template = configure.gettemplate (downlowType+". ftl"); En este momento, el archivo XML informará un error y, por supuesto, es imposible compilar y ejecutar el proyecto. Debe cambiar el archivo .xml a archivo .ftl para guardar. Luego compilar y ejecutar, representaciones:
Método 2: POI
Encontré muchos problemas de versión utilizando este método. Esto se basa en POI3.7+Word2007, y la prueba puede funcionar perfectamente.
Debe generar manualmente la plantilla de documento con Word2007 (usar otras generaciones causará un error: el archivo no se puede abrir) y reemplazar el contenido que debe actualizarse dinámicamente con $ {}, similar al anterior, pero no necesita guardarlo como un formato de documento XML.
/** * Personalizar xwpfDocument y anular createPicte () método * @author Joanna.yan * */public class CustomXWPFDocument extiende xwpfDocument {public customXWPFDocument (inputStream in) lanza ioexception {super (in); } public CustomXWPFDocument () {super (); } public CustomXWPFDocument (OPCPackage PKG) lanza IOException {super (PKG); } public void CreatePicture (int id, int width, int height, xwpfpargraph párrafo) {final int emu = 9525; ancho *= emu; altura *= emu; String Blipid = ((POIXMLDOCUMENTPART) getAllPictures (). Get (id)). GetPackagerelationship (). GetId (); Ctinline inline = párrafo.createrUn (). GetCtr (). AddnewDrawing (). AddnewinLine (); String picxml = "" + "<a: graphic xmlns: a =/" http://schemas.openxmlformats.org/drawingml/2006/main/ ">" + "<a: graphicData uri =/" http://schemas.openxmlformats.org/drawingml/2006/pture/ ">" ". + "<Pic: Pic xmlns: pic =/" http://schemas.openxmlformats.org/drawingml/2006/picture/ ">" + "<pic: nvpicpr>" + "<pic: cnvpr id =/" + id + "/" name =/"generado/"/> " +" <pic: cnvp/> " +" </pic:nvPicPr>" + " <pic:blipFill>" + " <a:blip r:embed=/"" + blipId + "/" xmlns:r=/"http://schemas.openxmlformats.org/officeDocument/2006/relationships/"/>" + " <a:stretch>" + " <a:fillRect/>" + " </a: estirar> " +" </pic: blipfill> " +" <pic: spPr> " +" <a: xfrm> " +" <a: off x =/"0/" y =/"0/"/> " +" <a: ext cx =/"" width + "/" cy =/" + altura +"/"/>" + "</a: x>" prst =/"rect/"> " +" <a: avlst/> " +" </a: prstgeom> " +" </pic: spPr> " +" </pic: pic> " +" </a: graphicData> " +" </a: gráfico> "; inline.addnewgraphic (). AddnewGraphicData (); XmlToken xmlToken = null; intente {xmlToken = xmltoken.factory.parse (picxml); } catch (xmlexception e) {E.PrintStackTrace (); } inline.set (xmlToken); inline.setDistt (0); inline.setDistb (0); inline.setDistl (0); inline.setdistr (0); CTPositiveSize2D Extent = inline.addnewextent (); extensión.setcx (ancho); extensión.setcy (altura); CtnonVisualDrawingProps docpr = inline.addNewDocpr (); docpr.setId (id); docpr.setName ("imagen"+id); docpr.setDescr ("test"); }} /** * Adecuado para Word 2007 * POI Versión 3.7 * @author Joanna.yan * */public class Wordutil {public static customxwpfDocument generateword (map <string, object> param, string plantate) {customxwpfdocument doc = null; Pruebe {OPCPackage Pack = PoIXMDocument.OpenPackage (plantilla); doc = new CustomXWPFDocument (Pack); if (param! = null & ¶m.size ()> 0) {// Processing Parraph List <XWPFPraph> PARAGRAPHLIST = DOC.GETPARAPRAPHS (); ProcessParraphs (ParapraphList, Param, DOC); // Tabla de procesamiento iterador <XWPFTable> it = doc.gettablesIterator (); while (it.hasnext ()) {xwpftable table = it.next (); Lista <XWPFTablerow> ROWS = TABLE.GETROWS (); for (xwpftablerow fila: filas) {list <XwpftableCell> Cells = Row.gettableCells (); for (xwpftableCell Cell: Cells) {list <XWPFParagraph> PARAGRAPHLISTTABLE = CELL.GETPARAPHS (); ProcessParraphs (PARAGRAPHLISTTABLE, PARAM, DOC); }}}}}} Catch (ioException e) {E.PrintStackTrace (); } return doc; } / ** * Párrafo de proceso * @param párrafo * @param param * @param doc * / public static void processpargraphs (list <xwpfpargraph> párrafo, map <tring, objeto> param, customxwpfDocument Doc) {if (párrafo : PARAGRAPHLIST) {LIST <XWPFRUN> Runs = PARAGRAPH.GETRUNS (); for (xwpfrun run: runs) {string text = run.gettext (0); if (text! = null) {boolean issetText = false; for (Entry <String, Object> Entry: Param.EntrySet ()) {String Key = Entry.getKey (); if (text.IndexOf (Key)! =-1) {issetText = true; Valor de objeto = entry.getValue (); if (value instanceOf string) {// Text Reemplazo Text = Text.replace (Key, value.ToString ()); } else if (value instanceOf map) {// Imagen reemplazo text = text.replace (clave, ""); Mapa pic = (mapa) valor; int width = integer.ParseInt (pic.get ("ancho"). toString ()); int hight = Integer.ParseInt (pic.get ("altura"). toString ()); int pictype = getPicteRetype (pic.get ("type"). toString ()); byte [] byteArray = (byte []) pic.get ("contenido"); ByteArrayInputStream byteInputStream = new byteArrayInputStream (byteArray); intente {int ind = doc.AddPicture (byteInputStream, pictype); doc.createPicture (ind, ancho, altura, párrafo); } catch (InvalIdFormateException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); }}}}}} if (issetText) {run.setText (texto, 0); }}}}}}}} / ** * Obtenga el código de tipo de imagen correspondiente de acuerdo con el tipo de imagen * @param pictype * @return * / public static int getPictureType (String pictype) {int res = customxwpfdocument.picture_type_pict; if (pictype! = null) {if (pictype.equalSignorEcase ("png")) {res = customXwpfDocument.picture_type_png; } else if (pictype.equalSignorEcase ("dib")) {res = customXwpfDocument.picture_type_dib; } else if (pictype.equalSignorEcase ("emf")) {res = customXwpfDocument.picture_type_emf; } else if (pictype.equalSignorEcase ("jpg") || pictype.equalSignorecase ("jpeg")) {res = customxwpfdocument.picture_type_jpeg; } else if (pictype.equalSignorecase ("wmf")) {res = customXwpfDocument.picture_type_wmf; }} return Res; }} public class testpoi {public static void main (string [] args) lanza ioexception {map <string, object> param = new HashMap <String, Object> (); param.put ("$ {name}", "Joanna.yan"); param.put ("$ {examnum}", "0000000000000001"); param.put ("$ {idcard}", "1111111111111111111111111111"); param.put ("$ {carmodel}", "c1"); CustomXWPFDocument doc = wordutil.generateword (param, "d: //joanna.docx"); FileOutputStream fopts = new FileOutputStream ("d: //yan.docx"); doc.write (fopts); fopts.close (); }}Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.