À l'origine, nous voulions générer des documents du côté Android (cela nécessite ...). En fin de compte, il n'y a pas de bonne méthode qui peut être parfaite sur Android, et en fin de compte, nous ne pouvons que passer au serveur. Ne le gaspillez pas, mais enregistrez les raisons pour lesquelles chaque cadre ne prend pas en charge Android et leurs caractéristiques. Il existe encore de nombreux cadres liés à Java, et certains ne sont pas mauvais, mais malheureusement, ils ne prennent pas en charge Android, soit ils facturent des frais et ont un prix bas.
Après des tests personnels, de nombreux packages AWT qui ne prennent pas en charge Java ne peuvent pas être utilisés directement sur Android. Freemarker est assez bon et peut générer des documents complexes et magnifiques, mais malheureusement, il ne prend pas en charge Android. Il peut fonctionner sur Android en utilisant POI, mais il a traversé de nombreux pièges en cours de route en raison de la version, du format, etc., et il est toujours brouillé d'ouvrir avec WFS. JWord et Aspose.Word peuvent être parfaitement pris en charge, et la période de probation JWord n'est que de 30 jours, les deux facturer pour les deux. ITEXT n'a pas de test, mais il est dit qu'il ne prend pas en charge Android.
Méthode 1: freemarker
Cette méthode nécessite la création manuelle d'un modèle de DOC (n'oubliez pas d'utiliser des espaces réservés pour l'image) et de l'enregistrer en tant que fichier XML. Générer en remplaçant dynamiquement le contenu dans la balise spécifique $ {}. exemple:
Tout d'abord, prenons les rendus:
classe publique Docutil {Public Configuration Configuration = NULL; public docutil () {configure = new configuration (configuration.version_2_3_22); configure.setDefaultEncoding ("UTF-8"); } / ** * Générer un fichier Word basé sur le modèle DOC * @param dataMap Les données qui doivent être remplies dans le modèle * @param téléchargement de fichier Nom * @param SavePath Save Path * / public void CreatedOC (map <string, objet> dataMap, String downloadType, TEmplate SAYPATH) {try {// Charger le template qui doit être chargé du modèle de modèle de modèle pour charger = null; // Définissez la méthode et le chemin du périphérique de modèle, Freemarker prend en charge plusieurs méthodes de chargement de modèle. Vous pouvez recharger le servlet, le chemin de classe et le support de base de données. // Chargez le fichier de modèle et placez-le sous TestDoc Configure.SetClassForTemplateLoading (this.getClass (), "/ testDoc"); // Définissez l'objet wrapper // configure.setObjectWrapper (new defaultObjectWrapper ()); // Définissez le gestionnaire d'exception configure.setTemplateExceptionHandler (templateExceptionHandler.ignore_handler); // Définissez l'objet de modèle, notez que le nom du type de modèle doit être cohérent avec le modèle de téléchargement = configure.getTemplate (DownloadType + ". Xml"); File outfile = new File (SavePath); Écrivain out = null; 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 dans = null; octet [] data = null; try {in = new FileInputStream (imgFile); data = nouveau octet [in.available ()]; in.read (données); joindre(); } catch (filenotFoundException e) {e.printStackTrace (); } catch (ioException e) {e.printStackTrace (); } Base64Encoder Encoder = new Base64Encoder (); return Encoder.encode (données); }} classe publique testDoc {public static void main (String [] args) {docutil docutil = new docutil (); Map <string, objet> dataMap = new HashMap <String, objet> (); dataMap.put ("nom", "Joanna"); dataMap.put ("examen", "1111111111111"); datamap.put ("idcard", "22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 222222222222222222222222222222222222222222222222222222222222222222222222222; DATAMAP.PUT (Carmodel "," C1 "); Docutil.getImagestr (d: //img//userimg1.png "); DATAMAP.PUT ("FirstExamScore", "0 Points, Échec"); Datamap.put ("FirstPic2", docutil.getImagestr (d: //img//firstpic2.png "); "12: 46: 50-13: 05: 37"); dataMap.put ("SecondExamscors", "90 points, pass"); dataMap.put ("SecondDeductItem", ""); 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, "Basedoc", "d: //yanqiong.doc"); }} Le fichier XML est trop long, donc je ne le publierai pas ...
Enfin, la raison pour laquelle Android ne peut pas être utilisé: http://stackoverflow.com/questions/25929542/use-fremarker-library-in-android
Questions supplémentaires sur l'affichage dynamique des listes et des pauses de ligne
L'exigence est claire: dans l'élément de déduction ci-dessus, si j'ai plusieurs éléments de déduction, je veux que chaque pause de ligne soit affichée.
L'ajout de nouvelles lignes au contenu à afficher n'a aucun effet et ne fonctionnera pas comme une nouvelle ligne.
Lors de l'ajout de balises FTL, telles que <#List> </Sist>, certains problèmes surviendront, qui ne sont pas reconnus dans le XML, ce qui entraînera le fait de ne pas être exécuté.
résoudre:
Ajouter et ajouter des ruptures de ligne à la position où plusieurs éléments de déduction doivent être affichés:
<#List FirstDeduCitem comme FirstItem>
<w: t> $ {FirstItem} </ w: t> <w: Br />
</ # liste>
Changez-le en:
List <string> strs = new ArrayList <string> ();
Str.add ("1111111111111111");
Str.add ("22222222222222222222222222);
Str.add ("3333333333333");
dataMap.put ("FirstDeduCitem", STRS);
Changez-le en docutil.java:
// Définissez l'objet de modèle, notez que le nom du type de modèle doit être cohérent avec le téléchargement
template = configure.getTemplate (DownloadType + ". Ftl"); À l'heure actuelle, le fichier XML rapportera une erreur, et bien sûr, il est impossible de compiler et d'exécuter le projet. Vous devez modifier le fichier .xml en fichier .ftl pour enregistrer. Puis compilez et exécutez, rendu:
Méthode 2: POI
J'ai rencontré de nombreux problèmes de version en utilisant cette méthode. Ceci est basé sur POI3.7 + Word2007, et le test peut fonctionner parfaitement.
Vous devez générer manuellement le modèle de document avec Word2007 (l'utilisation d'autres générations provoquera une erreur: le fichier ne peut pas être ouvert) et remplacer le contenu qui doit être mis à jour dynamiquement avec $ {}, similaire à ce qui précède, mais vous n'avez pas besoin de l'enregistrer sous forme de format de document XML.
/ ** * Personnaliser XWPFDocument et Override CreatePicture () Méthode * @Author Joanna.yan * * / classe publique CustomXWPFDocument étend xwpfDocument {public CustomXWPFDocument (InputStream in) lance ioException {super (in); } public CustomXWPFDocument () {super (); } public CustomXWPFDocument (OPCPackage PKG) lève ioException {super (pkg); } public void CreatePicture (int id, int larget, int hauteur, xwpfparagraph paragraph) {final int emu = 9525; largeur * = emu; hauteur * = emu; String bliPid = ((POIXMLDocumentPart) getAllPictures (). Get (id)). GetPackageLelationship (). GetID (); CTinline inline = paragraph.createrun (). GetCtr (). AddNewDrawing (). AddNewInline (); String picxml = "" + "<a: graphique xmlns: a = /" http://schemas.openxmlformats.org/drawingml/2006/main/ ">" + "<a: graphicdata uri = / "http://schemas.openxmlformats.org/drawingml/2006/picture/"> "+" <pic: pic xmlns: pic = / "http://schemas.openxmmlns.org/drawingml/2006/picture/"> "+" <pic: cnvpr id = / "" + id + "/" name = / "généré /" /> "+" <pic: cnvpicpr /> "+" </ pic: nvpicpr> "+" <pic: blipfill> "+" <a: blip r: embed = / "" + blipid + "/" xmlns: r = / "http://schemas.openxmlformats.org/officedocument/2006/relationships/" /> "+" <a: stretch> "+" <a: fillrect /> "+" </ a: stretch> "+" </ pic: blipfil x = / "0 /" y = / "0 /" /> "+" <a: ext cx = / "" + width + "/" cy = / "" + height + "/" /> "+" </ a: xfrm> "+" <a: prstgeom prst = / "rect /"> "+" <a: avlst /> "+" </ a: PRSTGEOM </ pic: pic> "+" </ a: graphicData> "+" </s: graphic> "; inline.AddNewGraphic (). AddNewGraphicData (); Xmltoken xmltoken = null; essayez {xmltoken = xmltoken.factory.parse (picxml); } catch (xmlexception e) {e.printStackTrace (); } inline.set (xmltoken); inline.setDistt (0); inline.setDistB (0); inline.setDistl (0); inline.setDist (0); CtpositiveSize2d extension = inline.addnewExtent (); extend.setcx (largeur); extension.setcy (hauteur); CtNonVisualDrawingProps docpr = inline.addnewdocpr (); docpr.setid (id); docpr.setName ("image" + id); docpr.setdescr ("test"); }} / ** * Convient pour Word 2007 * POI version 3.7 * @author joanna.yan * * / classe publique WordUtil {public static customXwpfDocument generateword (map <string, object> param, string template) {customXwpfDocument doc = null; essayez {opcpackage pack = POIXMLDocument.OpenPackage (modèle); doc = new CustomXWPFDocument (pack); if (param! = null & ¶m.Size ()> 0) {// Traiter la liste des paragraphes <xwpfParagraph> paragraphList = doc.getParagraphs (); processParagraphs (paragraphlist, param, doc); // Traitement Table Iterator <xwpftable> it = doc.getTableSiterator (); while (it.hasnext ()) {xwpftable table = it.next (); List <xwpftableRow> wows = table.getRows (); pour (xwpftableRow row: lignes) {list <xwpftablecell> celaires = row.getTableCells (); pour (xwpftableCell Cell: Cell) {list <xwpfParagraph> paragraphListTable = Cell.getParagraphs (); processParagraphs (paragraphListTable, param, doc); }}}}}} catch (ioException e) {e.printStackTrace (); } return doc; } / ** * Paragraphe de processus * @param paragraphlist * @param param * @param doc * / public static void processParagraphs (list <xwpfparagraph> paragraphlist, map <string, object> param, customXwpfDocument doc) {if (paragraphlist! = Null & ¶graphList.Size ()> 0) {pour (xwpfara ParagraphList) {list <xwpfrun> runs = paragraph.getRuns (); for (xwpfrun run: runs) {String text = run.getText (0); if (text! = null) {boolean isseTTeTText = false; pour (entrée <string, objet> entrée: param.entrySet ()) {string key = entry.getKey (); if (text.indexof (key)! = - 1) {isseTText = true; Valeur objet = entrée.getValue (); if (valeur instanceOf String) {// Text remplacement text = text.replace (key, value.toString ()); } else if (valeur instanceof map) {// image remplacement text = text.replace (key, ""); Map pic = (map) valeur; int width = Integer.ParseInt (pic.get ("width"). toString ()); int height = Integer.ParseInt (pic.get ("height"). toString ()); int picType = getPictureType (pic.get ("type"). toString ()); Byte [] bytearray = (byte []) pic.get ("contenu"); BytearrayInputStream byteInputStream = new bytearrayInputStream (bytearray); try {int Ind = doc.addPicture (byteInputStream, picType); Doc.CreatePicture (Ind, largeur, hauteur, paragraphe); } catch (invalidformatexception e) {e.printStackTrace (); } catch (ioException e) {e.printStackTrace (); }}}}}} if (isseTTeXt) {run.seTTeXt (texte, 0); }}}}}}}}} / ** * Obtenez le code de type d'image correspondant en fonction du type d'image * @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; }} classe publique TestPoi {public static void main (string [] args) lève ioException {map <string, object> param = new hashmap <string, object> (); param.put ("$ {name}", "joanna.yan"); param.put ("$ {examnum}", "0000000000000001"); param.put ("$ {idcard}", "11111111111111111111111111"); param.put ("$ {carmodel}", "c1"); CustomXwpfDocument doc = wordutil.generateword (param, "d: //joanna.docx"); FileOutputStream fopts = new FileOutputStream ("d: //yan.docx"); doc.write (fopts); fopts.close (); }}Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.