Первоначально мы хотели генерировать документы на стороне Android (это требует ...). В конце концов, нет хорошего метода, который может быть идеальным на Android, и, в конце концов, мы можем перейти только на сервер. Не тратьте его впустую, но записывайте причины, по которым каждая структура не поддерживает Android и их характеристики. Есть еще много таких структур, связанных с Java, а некоторые не плохи, но, к сожалению, они либо не поддерживают Android, либо взимают плату и имеют низкую цену.
После личного тестирования многие пакеты AWT, которые не поддерживают Java, не могут быть использованы непосредственно на Android. Freemarker довольно хорош и может генерировать сложные и красивые документы, но, к сожалению, он не поддерживает Android. Он может работать на Android, используя POI, но на этом пути он прошел много ловушек из -за версии, формата и т. Д., И все еще искажается для открытия WFS. JWord and Aspose.Word можно идеально поддерживать, а испытательный срок JWord составляет всего 30 дней, оба взимаются за обоих. У ITEXT нет теста, но говорят, что он не поддерживает Android.
Метод 1: Freemarker
Этот метод требует вручную создать шаблон DOC (не забудьте использовать заполнители для картинки) и сохранить его в качестве файла XML. Создать путем динамической замены контента в конкретной теге $ {}. пример:
Во -первых, давайте возьмем визуализации:
открытый класс docutil {public configuration configuration = null; public Docutil () {configure = новая конфигурация (configuration.version_2_3_22); configure.setDefaultEncoding ("UTF-8"); } /** * Generate word file based on Doc template* @param dataMap The data that needs to be filled in the template* @param downloadType File name* @param savePath Save path*/ public void createDoc(Map<String,Object> dataMap,String downloadType,String savePath){ try { //Load the template that needs to be loaded Template template=null; // Установите метод и путь устройства шаблона, Freemarker поддерживает множество методов загрузки шаблонов. Вы можете перезагрузить сервлет, класс и базы данных. // Загрузите файл шаблона и поместите его в TestDoc configure.setClassFortemplayLateLoading (this.getClass (), "/testDoc"); // Установить объект обертки // configure.setObjectWrapper (new DefaultObjectWrapper ()); // Установить обработчик исключений configure.setTemplateExceptionHandler (TemplateExceptionHandler.ignore_handler); // Определите объект шаблона, обратите внимание, что имя типа шаблона должно соответствовать шаблону загрузки Type = configure.getTemplate (DownloadType+". Xml"); File outfile = new File (savePath); Писатель Out = null; out = new BufferedWriter (новый outputStreamWriter (new FileOutputStream (Outfile), "UTF-8")); Template.process (dataMap, out); out.close (); } catch (ioException e) {e.printstackTrace (); } catch (templateException e) {e.printstacktrace (); }} public String getImageSt (String imgfile) {inputStream in = null; byte [] data = null; try {in = new FileInputStream (imgfile); data = new Byte [in.vailable ()]; in.read (data); in.close (); } catch (filenotFoundException e) {e.printstackTrace (); } catch (ioException e) {e.printstackTrace (); } Base64encoder encoder = new Base64encoder (); вернуть encoder.encode (data); }} открытый класс testdoc {public static void main (string [] args) {docutil docutil = new Docutil (); Map <string, object> dataMap = new hashmap <string, object> (); dataMap.put ("имя", "Джоанна"); dataMap.put ("examnum", "11111111111111111"); dataMap.put ("idcard", «222222222222222222222222222222222222222222222222222222222222222222222 2222222222222222222222222222222222222222222222222222222222222222222222; DataMap.put ("Carmodel", "C1"); docutil.getimageSt ("d: //img//userimg1.png")); dataMap.put ("FirstExamscores", "0 Points, Faile"); dataMap.put ("FirstPic2", docutil.getimageSt ("d: //img//firstpic2.png"); "12: 46: 50-13: 05: 37"); dataMap.put ("SecondExamScores", "90 Points, Pass"); dataMap.put ("seconddeductiTem", ""); dataMap.put ("secondpic1", docutil.getimageSt ("d: //img//secondpic1.png")); dataMap.put ("secondpic2", docutil.getimageSt ("d: //img//secondpic2.png")); dataMap.put ("secondpic3", docutil.getimageSt ("d: //img//secondpic3.png")); docutil.createdoc (datamap, "basedoc", "d: //yanqiong.doc"); }} Файл XML слишком длинный, поэтому я не буду публиковать его ...
Наконец, причина, по которой Android не может быть использован: http://stackoverflow.com/questions/25929542/use-freemarker-library-in-android
Дополнительные вопросы о динамическом отображении списков и разрывах строк
Требование ясно: в приведенном выше элементе вычета, если у меня есть несколько элементов вычета, я хочу, чтобы каждый разрыв в строке был отображен.
Добавление новичков непосредственно в отображаемое содержимое не имеет никакого эффекта и не будет функционировать как новая линия.
При добавлении тегов FTL, таких как <#list> </list>, возникают некоторые проблемы, которые не распознаются в XML, в результате чего проект не может работать.
решать:
Добавьте и добавьте разрывы в линии в положение, где необходимо отобразить несколько элементов вычета:
<#list FirstdeductiTem как FirstItem>
<w: t> $ {firstitem} </w: t> <w: br/>
</#список>
Изменить это на:
Список <string> strs = new ArrayList <string> ();
Strs.add ("1111111111111111111111);
Strs.add ("22222222222222222222222222);
Strs.add ("33333333333333");
dataMap.put ("FirsteductiTem", Strs);
Изменить это на Docutil.java:
// Определите объект шаблона, обратите внимание, что имя типа шаблона должно соответствовать загрузке
template = configure.getTemplate (downloadType+". ftl"); В настоящее время файл XML сообщит об ошибке, и, конечно, невозможно компилировать и запустить проект. Вам нужно изменить файл .xml на файл .ftl для сохранения. Затем компилируйте и запускайте, визуализируются:
Метод 2: POI
Я столкнулся со многими проблемами версий, используя этот метод. Это основано на POI3.7+Word2007, и тест может работать идеально.
Вам необходимо вручную генерировать шаблон документа с помощью Word2007 (использование других поколений вызовет ошибку: файл не может быть открыт), и заменить контент, который необходимо динамически обновляться с помощью $ {}, аналогично вышеуказанному, но вам не нужно сохранять его как формат документа XML.
/** * Настроить xwpfdocument и переопределить метод CreatePicture () * @author joanna.yan * */public class customxwpfdocument extends xwpfdocument {public customxwpfdocument (inputStream in) throws ioException {super (in); } public customxwpfdocument () {super (); } public customxwpfdocument (opcpackage pkg) бросает ioexception {super (pkg); } public void createPicture (int id, int width, int height, xwpfparagraph paragraph) {final int emu = 9525; ширина *= emu; высота *= эму; String blipid = ((poixmldocumentpart) getAllpictures (). Get (id)). GetPackagerElationship (). GetId (); Ctinline inline = paragraph.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/picture/"> " +" <pic: pic xmlns: pic =/"http://schemas.openxmlformats.org/drawingml/2006/picture/" + "PICPIC/Drawingml/2006/picture/" + "PICPIC/nvpiC/DRAWINGML/2006/picture/ <pic: cnvpr id =/"" + id + "/" name =/"сгенерировано/"/> " +" <pic: cnvpicpr/> " +" </pic: nvpicpr> " +" <pic: blipfill> " +" <a: blip r: embed =/"" + blipid + "/" xmlns: r =/"http://schemas.openxmlformats.org/officeedocument/2006/relationships/"/> " +" <a: streant> " +" <A: FillRect/> " +" </a: streat> " +" </pic: blipfill> " +" <IC: SPPR> "<и:" <и "</pic:" (A OFF> "<Appr>" <и PIC: "</FR> x =/"0/" y =/"0/"/> " +" <a: ext cx =/"" + width + "/" cy =/"" + height + "/"/> " +" </a: xfrm> " +" <a: prstgeom prst =/"rect/"> " +" <a: avlst/> " +" </a: prstge> " +" + "</a: pis)" + "</apstge. </pic: pic> " +" </a: graphicdata> " +" </a: graphic> "; inline.addnewgraphic (). addnewgraphicdata (); Xmltoken xmltoken = null; try {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 (); extent.setcx (ширина); extent.setcy (высота); Ctnonvisualdrawingprops docpr = inline.addnewdocpr (); docpr.setid (id); docpr.setname ("Image"+id); docpr.setdescr ("test"); }} /** * Подходит для Word 2007 * POI версия 3.7 * @author joanna.yan * */public class wordutil {public static customxwppfdocument Generateword (map <String, объект> Param, String Template) {CustomXWPFDocument DOC = NULL; try {opcpackage pack = poixmldocument.openpackage (шаблон); doc = new CustomXwpfdocument (pack); if (param! = null & ¶m.size ()> 0) {// Обработка параграфа список <xwpfparagraph> paragraphlist = doc.getParagraphs (); Procesparagraphs (Paragraphlist, Param, Doc); // Обработка таблицы итератор <xwpftable> it = doc.getTablesiterator (); while (it.hasnext ()) {xwpftable table = it.next (); Список <xwpftablerow> rows = table.getrows (); for (xwpftableerow row: row) {list <xwpftablecell> cells = row.getTableCells (); для (xwpftablecell: ячейки) {list <xwpfparagraph> paragraphlisttable = cell.getParagraphs (); Procesparagraphs (Paragraphlisttable, Param, Doc); }}}}}} catch (ioException e) {e.printstacktrace (); } return doc; } / ** * Процесс -параграф * @param paragraphlist * @param param * @param doc * / public static void processparacraphs (список <xwpfparagraph> paragraphlist, map <string> param, customxwpfdocument doc) {if (paragraphlist! 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; Значение объекта = entry.getValue (); if (value ancessionof String) {// Текст замена текста = text.replace (key, value.tostring ()); } else if (exanceOf instanceOf map) {// Замена изображения text = text.Replace (key, ""); Карта pic = (map) значение; 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 ("content"); BytearrayinputStream byteinputstream = new Bytearrayinputstream (Bytearray); try {int ind = doc.addpicture (byteinputstream, pictype); doc.createpicture (ind, ширина, высота, абзац); } catch (InvalidFormateXception e) {e.printstackTrace (); } catch (ioException e) {e.printstackTrace (); }}}}}} if (issettext) {run.settext (text, 0); }}}}}}}} / ** * Получить соответствующий код типа изображения в соответствии с типом изображения * @param pictype * @return * / public static int getPictureType (string pictype) {int res = customxwppdocument.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) бросает ioException {map <string, object> param = new hashmap <string, object> (); param.put ("$ {name}", "joanna.yan"); param.put ("$ {exmbremnum}", "00000000000001"); param.put ("$ {idcard}", "1111111111111111111111111111"); param.put ("$ {carmodel}", "C1"); CustomXWPFDOCUMEM DOC = WORDUTIL.GenerateWord (param, "d: //joanna.docx"); FileOutputStream fopts = new FileOutputStream ("d: //yan.docx"); doc.write (fopts); fopts.close (); }}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.